about summary refs log tree commit diff
path: root/library/core
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2023-03-07 13:17:59 +0000
committerbors <bors@rust-lang.org>2023-03-07 13:17:59 +0000
commit160c2ebeca7b4e616962134f230de754fa5433b1 (patch)
tree462d6f62ac5d604e66ca4f66876224bc706894ba /library/core
parent0a3b557d528dd7c8a88ceca6f7dc0699b89a3ef4 (diff)
parent3554036280525cec34103a8f66049b0881b14d27 (diff)
downloadrust-160c2ebeca7b4e616962134f230de754fa5433b1.tar.gz
rust-160c2ebeca7b4e616962134f230de754fa5433b1.zip
Auto merge of #108763 - scottmcm:indexing-nuw-lengths, r=cuviper
Use `nuw` when calculating slice lengths from `Range`s

An `assume` would definitely not be worth it, but since the flag is almost free we might as well tell LLVM this, especially on `_unchecked` calls where there's no obvious way for it to deduce it.

(Today neither safe nor unsafe indexing gets it: <https://rust.godbolt.org/z/G1jYT548s>)
Diffstat (limited to 'library/core')
-rw-r--r--library/core/src/slice/index.rs9
1 files changed, 6 insertions, 3 deletions
diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs
index f0e5ea53d7d..3539353240a 100644
--- a/library/core/src/slice/index.rs
+++ b/library/core/src/slice/index.rs
@@ -2,6 +2,7 @@
 
 use crate::intrinsics::assert_unsafe_precondition;
 use crate::intrinsics::const_eval_select;
+use crate::intrinsics::unchecked_sub;
 use crate::ops;
 use crate::ptr;
 
@@ -375,14 +376,15 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
         // SAFETY: the caller guarantees that `slice` is not dangling, so it
         // cannot be longer than `isize::MAX`. They also guarantee that
         // `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
-        // so the call to `add` is safe.
+        // so the call to `add` is safe and the length calculation cannot overflow.
         unsafe {
             assert_unsafe_precondition!(
                 "slice::get_unchecked requires that the range is within the slice",
                 [T](this: ops::Range<usize>, slice: *const [T]) =>
                 this.end >= this.start && this.end <= slice.len()
             );
-            ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), self.end - self.start)
+            let new_len = unchecked_sub(self.end, self.start);
+            ptr::slice_from_raw_parts(slice.as_ptr().add(self.start), new_len)
         }
     }
 
@@ -396,7 +398,8 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
                 [T](this: ops::Range<usize>, slice: *mut [T]) =>
                 this.end >= this.start && this.end <= slice.len()
             );
-            ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), self.end - self.start)
+            let new_len = unchecked_sub(self.end, self.start);
+            ptr::slice_from_raw_parts_mut(slice.as_mut_ptr().add(self.start), new_len)
         }
     }