Auto merge of #124793 - scottmcm:simplify-as-chunks, r=Nilstrieb

Implement `as_chunks` with `split_at_unchecked`

We were discussing various ways to do [this on Discord](https://discord.com/channels/273534239310479360/273541522815713281/1236946363120619521), and in the process I noticed that <https://rust.godbolt.org/z/1P16P37Go> is emitting a panic path inside `as_chunks`.  It optimizes out in release, but we could just not do that in the first place.

We're already doing unsafe code that depends on this value being calculated correctly, so might as well call `split_at_unchecked` instead of `split_at`.
This commit is contained in:
bors 2024-05-09 01:55:46 +00:00
commit ee9a9f84c5

View File

@ -1337,8 +1337,10 @@ impl<T> [T] {
#[must_use]
pub const fn as_chunks<const N: usize>(&self) -> (&[[T; N]], &[T]) {
assert!(N != 0, "chunk size must be non-zero");
let len = self.len() / N;
let (multiple_of_n, remainder) = self.split_at(len * N);
let len_rounded_down = self.len() / N * N;
// SAFETY: The rounded-down value is always the same or smaller than the
// original length, and thus must be in-bounds of the slice.
let (multiple_of_n, remainder) = unsafe { self.split_at_unchecked(len_rounded_down) };
// SAFETY: We already panicked for zero, and ensured by construction
// that the length of the subslice is a multiple of N.
let array_slice = unsafe { multiple_of_n.as_chunks_unchecked() };
@ -1487,8 +1489,10 @@ impl<T> [T] {
#[must_use]
pub const fn as_chunks_mut<const N: usize>(&mut self) -> (&mut [[T; N]], &mut [T]) {
assert!(N != 0, "chunk size must be non-zero");
let len = self.len() / N;
let (multiple_of_n, remainder) = self.split_at_mut(len * N);
let len_rounded_down = self.len() / N * N;
// SAFETY: The rounded-down value is always the same or smaller than the
// original length, and thus must be in-bounds of the slice.
let (multiple_of_n, remainder) = unsafe { self.split_at_mut_unchecked(len_rounded_down) };
// SAFETY: We already panicked for zero, and ensured by construction
// that the length of the subslice is a multiple of N.
let array_slice = unsafe { multiple_of_n.as_chunks_unchecked_mut() };