about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--library/core/src/slice/mod.rs40
1 files changed, 17 insertions, 23 deletions
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index f028d68baea..8ad3c414454 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -559,27 +559,24 @@ impl<T> [T] {
             // Use the llvm.bswap intrinsic to reverse u8s in a usize
             let chunk = mem::size_of::<usize>();
             while i + chunk - 1 < ln / 2 {
-                // SAFETY: An unaligned usize can be read from `i` if `i + 1 < ln`
-                // (and obviously `i < ln`), because each element is 1 byte and
-                // we're reading `chunk`.
+                // SAFETY:
                 //
-                // Since we checked for the `x86` and `x86_64` target before
-                // getting here so `chunk` is at most 8 bytes.
-                //
-                // `i + chunk - 1 < ln / 2` # while condition
-                // `i + 8 - 1 < ln / 2`
-                // `i + 7 < ln / 2`
-                // so obviously `i + 1 < ln / 2`
-                //
-                // Since it's less than the length divided by 2, then it must be
-                // in bounds.
-                //
-                // This also means that the condition `0 < i + chunk <= ln` is
-                // always respected, ensuring the `pb` pointer can be used
-                // safely.
-                //
-                // Note: when updating this comment, update the others in the
-                // function too.
+                // - Note that `chunk` is either 4 or 8 due to the cfg check
+                //   above. So `chunk - 1` is positive.
+                // - Indexing with index `i` is fine as the loop check guarantees
+                //   `i + chunk - 1 < ln / 2`
+                //   <=> `i < ln / 2 - (chunk - 1) < ln / 2 < ln`.
+                // - Indexing with index `ln - i - chunk = ln - (i + chunk)` is fine:
+                //   - `i + chunk > 0` is trivially true.
+                //   - The loop check guarantees:
+                //     `i + chunk - 1 < ln / 2`
+                //     <=> `i + chunk ≤ ln / 2 ≤ ln`, thus subtraction does not underflow.
+                // - The `read_unaligned` and `write_unaligned` calls are fine:
+                //   - `pa` points to index `i` where `i < ln / 2 - (chunk - 1)`
+                //     (see above) and `pb` points to index `ln - i - chunk`, so
+                //     both are at least `chunk`
+                //     many bytes away from the end of `self`.
+                //   - Any initialized memory is valid `usize`.
                 unsafe {
                     let pa: *mut T = self.get_unchecked_mut(i);
                     let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);
@@ -610,9 +607,6 @@ impl<T> [T] {
                 // This also means that the condition `0 < i + chunk <= ln` is
                 // always respected, ensuring the `pb` pointer can be used
                 // safely.
-                //
-                // Note: when updating this comment, update the others in the
-                // function too.
                 unsafe {
                     let pa: *mut T = self.get_unchecked_mut(i);
                     let pb: *mut T = self.get_unchecked_mut(ln - i - chunk);