Skip to content

Commit cba05f7

Browse files
committed
Expand assumes to the other unchecked slice ops
1 parent 2f348cb commit cba05f7

File tree

2 files changed

+38
-3
lines changed

2 files changed

+38
-3
lines changed

library/core/src/slice/index.rs

+14-3
Original file line numberDiff line numberDiff line change
@@ -265,7 +265,10 @@ unsafe impl<T> SliceIndex<[T]> for usize {
265265
(this: usize = self, len: usize = slice.len()) => this < len
266266
);
267267
// SAFETY: see comments for `get_unchecked` above.
268-
unsafe { get_mut_noubcheck(slice, self) }
268+
unsafe {
269+
crate::intrinsics::assume(self < slice.len());
270+
get_mut_noubcheck(slice, self)
271+
}
269272
}
270273

271274
#[inline]
@@ -317,7 +320,10 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
317320
// cannot be longer than `isize::MAX`. They also guarantee that
318321
// `self` is in bounds of `slice` so `self` cannot overflow an `isize`,
319322
// so the call to `add` is safe.
320-
unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
323+
unsafe {
324+
crate::intrinsics::assume(self.end() <= slice.len());
325+
get_offset_len_noubcheck(slice, self.start(), self.len())
326+
}
321327
}
322328

323329
#[inline]
@@ -329,7 +335,10 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
329335
);
330336

331337
// SAFETY: see comments for `get_unchecked` above.
332-
unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
338+
unsafe {
339+
crate::intrinsics::assume(self.end() <= slice.len());
340+
get_offset_len_mut_noubcheck(slice, self.start(), self.len())
341+
}
333342
}
334343

335344
#[inline]
@@ -404,6 +413,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
404413
unsafe {
405414
// Using the intrinsic avoids a superfluous UB check,
406415
// since the one on this method already checked `end >= start`.
416+
crate::intrinsics::assume(self.end <= slice.len());
407417
let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
408418
get_offset_len_noubcheck(slice, self.start, new_len)
409419
}
@@ -422,6 +432,7 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
422432
);
423433
// SAFETY: see comments for `get_unchecked` above.
424434
unsafe {
435+
crate::intrinsics::assume(self.end <= slice.len());
425436
let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
426437
get_offset_len_mut_noubcheck(slice, self.start, new_len)
427438
}

tests/codegen/issues/issue-116878.rs

+24
Original file line numberDiff line numberDiff line change
@@ -9,3 +9,27 @@ pub unsafe fn unchecked_slice_no_bounds_check(s: &[u8]) -> u8 {
99
// CHECK-NOT: panic_bounds_check
1010
a + s[0]
1111
}
12+
13+
// CHECK-LABEL: @unchecked_slice_no_bounds_check_mut
14+
#[no_mangle]
15+
pub unsafe fn unchecked_slice_no_bounds_check_mut(s: &mut [u8]) -> u8 {
16+
let a = *s.get_unchecked_mut(2);
17+
// CHECK-NOT: panic_bounds_check
18+
a + s[1]
19+
}
20+
21+
// CHECK-LABEL: @unchecked_slice_no_bounds_check_range
22+
#[no_mangle]
23+
pub unsafe fn unchecked_slice_no_bounds_check_range(s: &[u8]) -> u8 {
24+
let _a = &s.get_unchecked(..1);
25+
// CHECK-NOT: panic_bounds_check
26+
s[0]
27+
}
28+
29+
// CHECK-LABEL: @unchecked_slice_no_bounds_check_range_mut
30+
#[no_mangle]
31+
pub unsafe fn unchecked_slice_no_bounds_check_range_mut(s: &mut [u8]) -> u8 {
32+
let _a = &mut s.get_unchecked_mut(..2);
33+
// CHECK-NOT: panic_bounds_check
34+
s[1]
35+
}

0 commit comments

Comments
 (0)