about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2024-05-09 01:55:46 +0000
committerbors <bors@rust-lang.org>2024-05-09 01:55:46 +0000
commitee9a9f84c599492eb9613292394d6d05d9f9e6ba (patch)
tree89e749b7038856353ff56e43c536bf100aa84f14
parent87293c9585a7fb2cc83ca9949ae79661d5d3c31a (diff)
parent49af347653beb2ee3b9c83b1beb741b63b86f211 (diff)
downloadrust-ee9a9f84c599492eb9613292394d6d05d9f9e6ba.tar.gz
rust-ee9a9f84c599492eb9613292394d6d05d9f9e6ba.zip
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`.
-rw-r--r--library/core/src/slice/mod.rs12
1 files changed, 8 insertions, 4 deletions
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 133cde8c097..9bee50424b3 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -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() };