Skip to content

Commit 61bcd82

Browse files
committed
Consolidate panicking functions in slice/index.rs
Consolidate all the panicking functions in `slice/index.rs` to use a single `slice_index_fail` function, similar to how it is done in `str/traits.rs`.
1 parent 2546221 commit 61bcd82

File tree

4 files changed

+66
-60
lines changed

4 files changed

+66
-60
lines changed

library/core/src/slice/index.rs

Lines changed: 61 additions & 55 deletions
Original file line numberDiff line numberDiff line change
@@ -34,36 +34,41 @@ where
3434
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
3535
#[cfg_attr(feature = "panic_immediate_abort", inline)]
3636
#[track_caller]
37-
const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
38-
const_panic!(
39-
"slice start index is out of range for slice",
40-
"range start index {index} out of range for slice of length {len}",
41-
index: usize,
42-
len: usize,
43-
)
44-
}
45-
46-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
47-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
48-
#[track_caller]
49-
const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
37+
const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
38+
if start > len {
39+
const_panic!(
40+
"slice start index is out of range for slice",
41+
"range start index {start} out of range for slice of length {len}",
42+
start: usize,
43+
len: usize,
44+
)
45+
}
46+
47+
if end > len {
48+
const_panic!(
49+
"slice end index is out of range for slice",
50+
"range end index {end} out of range for slice of length {len}",
51+
end: usize,
52+
len: usize,
53+
)
54+
}
55+
56+
if start > end {
57+
const_panic!(
58+
"slice index start is larger than end",
59+
"slice index starts at {start} but ends at {end}",
60+
start: usize,
61+
end: usize,
62+
)
63+
}
64+
65+
// Only reachable if the range was a `RangeInclusive` or a
66+
// `RangeToInclusive`, with `end == len`.
5067
const_panic!(
5168
"slice end index is out of range for slice",
52-
"range end index {index} out of range for slice of length {len}",
53-
index: usize,
54-
len: usize,
55-
)
56-
}
57-
58-
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never), cold)]
59-
#[cfg_attr(feature = "panic_immediate_abort", inline)]
60-
#[track_caller]
61-
const fn slice_index_order_fail(index: usize, end: usize) -> ! {
62-
const_panic!(
63-
"slice index start is larger than end",
64-
"slice index starts at {index} but ends at {end}",
65-
index: usize,
69+
"range end index {end} out of range for slice of length {len}",
6670
end: usize,
71+
len: usize,
6772
)
6873
}
6974

@@ -327,7 +332,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
327332
// SAFETY: `self` is checked to be valid and in bounds above.
328333
unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
329334
} else {
330-
slice_end_index_len_fail(self.end(), slice.len())
335+
slice_index_fail(self.start(), self.end(), slice.len())
331336
}
332337
}
333338

@@ -337,7 +342,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
337342
// SAFETY: `self` is checked to be valid and in bounds above.
338343
unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
339344
} else {
340-
slice_end_index_len_fail(self.end(), slice.len())
345+
slice_index_fail(self.start(), self.end(), slice.len())
341346
}
342347
}
343348
}
@@ -422,26 +427,27 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
422427
#[inline(always)]
423428
fn index(self, slice: &[T]) -> &[T] {
424429
// Using checked_sub is a safe way to get `SubUnchecked` in MIR
425-
let Some(new_len) = usize::checked_sub(self.end, self.start) else {
426-
slice_index_order_fail(self.start, self.end)
427-
};
428-
if self.end > slice.len() {
429-
slice_end_index_len_fail(self.end, slice.len());
430+
if let Some(new_len) = usize::checked_sub(self.end, self.start)
431+
&& self.end <= slice.len()
432+
{
433+
// SAFETY: `self` is checked to be valid and in bounds above.
434+
unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
435+
} else {
436+
slice_index_fail(self.start, self.end, slice.len())
430437
}
431-
// SAFETY: `self` is checked to be valid and in bounds above.
432-
unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
433438
}
434439

435440
#[inline]
436441
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
437-
let Some(new_len) = usize::checked_sub(self.end, self.start) else {
438-
slice_index_order_fail(self.start, self.end)
439-
};
440-
if self.end > slice.len() {
441-
slice_end_index_len_fail(self.end, slice.len());
442+
// Using checked_sub is a safe way to get `SubUnchecked` in MIR
443+
if let Some(new_len) = usize::checked_sub(self.end, self.start)
444+
&& self.end <= slice.len()
445+
{
446+
// SAFETY: `self` is checked to be valid and in bounds above.
447+
unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
448+
} else {
449+
slice_index_fail(self.start, self.end, slice.len())
442450
}
443-
// SAFETY: `self` is checked to be valid and in bounds above.
444-
unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
445451
}
446452
}
447453

@@ -553,7 +559,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
553559
#[inline]
554560
fn index(self, slice: &[T]) -> &[T] {
555561
if self.start > slice.len() {
556-
slice_start_index_len_fail(self.start, slice.len());
562+
slice_index_fail(self.start, slice.len(), slice.len())
557563
}
558564
// SAFETY: `self` is checked to be valid and in bounds above.
559565
unsafe { &*self.get_unchecked(slice) }
@@ -562,7 +568,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
562568
#[inline]
563569
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
564570
if self.start > slice.len() {
565-
slice_start_index_len_fail(self.start, slice.len());
571+
slice_index_fail(self.start, slice.len(), slice.len())
566572
}
567573
// SAFETY: `self` is checked to be valid and in bounds above.
568574
unsafe { &mut *self.get_unchecked_mut(slice) }
@@ -678,15 +684,15 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
678684
#[inline]
679685
fn index(self, slice: &[T]) -> &[T] {
680686
if *self.end() >= slice.len() {
681-
slice_end_index_len_fail(*self.end(), slice.len());
687+
slice_index_fail(self.start, self.end, slice.len())
682688
}
683689
self.into_slice_range().index(slice)
684690
}
685691

686692
#[inline]
687693
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
688694
if *self.end() >= slice.len() {
689-
slice_end_index_len_fail(*self.end(), slice.len());
695+
slice_index_fail(self.start, self.end, slice.len())
690696
}
691697
self.into_slice_range().index_mut(slice)
692698
}
@@ -840,22 +846,22 @@ where
840846
let len = bounds.end;
841847

842848
let end = match range.end_bound() {
843-
ops::Bound::Included(&end) if end >= len => slice_end_index_len_fail(end, len),
849+
ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
844850
// Cannot overflow because `end < len` implies `end < usize::MAX`.
845851
ops::Bound::Included(&end) => end + 1,
846852

847-
ops::Bound::Excluded(&end) if end > len => slice_end_index_len_fail(end, len),
853+
ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
848854
ops::Bound::Excluded(&end) => end,
849855

850856
ops::Bound::Unbounded => len,
851857
};
852858

853859
let start = match range.start_bound() {
854-
ops::Bound::Excluded(&start) if start >= end => slice_index_order_fail(start, end),
860+
ops::Bound::Excluded(&start) if start >= end => slice_index_fail(start, end, len),
855861
// Cannot overflow because `start < end` implies `start < usize::MAX`.
856862
ops::Bound::Excluded(&start) => start + 1,
857863

858-
ops::Bound::Included(&start) if start > end => slice_index_order_fail(start, end),
864+
ops::Bound::Included(&start) if start > end => slice_index_fail(start, end, len),
859865
ops::Bound::Included(&start) => start,
860866

861867
ops::Bound::Unbounded => 0,
@@ -985,22 +991,22 @@ pub(crate) fn into_slice_range(
985991
(start, end): (ops::Bound<usize>, ops::Bound<usize>),
986992
) -> ops::Range<usize> {
987993
let end = match end {
988-
ops::Bound::Included(end) if end >= len => slice_end_index_len_fail(end, len),
994+
ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
989995
// Cannot overflow because `end < len` implies `end < usize::MAX`.
990996
ops::Bound::Included(end) => end + 1,
991997

992-
ops::Bound::Excluded(end) if end > len => slice_end_index_len_fail(end, len),
998+
ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
993999
ops::Bound::Excluded(end) => end,
9941000

9951001
ops::Bound::Unbounded => len,
9961002
};
9971003

9981004
let start = match start {
999-
ops::Bound::Excluded(start) if start >= end => slice_index_order_fail(start, end),
1005+
ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
10001006
// Cannot overflow because `start < end` implies `start < usize::MAX`.
10011007
ops::Bound::Excluded(start) => start + 1,
10021008

1003-
ops::Bound::Included(start) if start > end => slice_index_order_fail(start, end),
1009+
ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
10041010
ops::Bound::Included(start) => start,
10051011

10061012
ops::Bound::Unbounded => 0,

library/coretests/tests/slice.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1513,7 +1513,7 @@ mod slice_index {
15131513
data: [0; 1];
15141514

15151515
bad: data[(Bound::Excluded(usize::MAX), Bound::Unbounded)];
1516-
message: "but ends at 1";
1516+
message: "out of range";
15171517
}
15181518
} // panic_cases!
15191519
}

tests/codegen-llvm/integer-overflow.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ pub struct S1<'a> {
1010
// CHECK-LABEL: @slice_no_index_order
1111
#[no_mangle]
1212
pub fn slice_no_index_order<'a>(s: &'a mut S1, n: usize) -> &'a [u8] {
13-
// CHECK-NOT: slice_index_order_fail
13+
// CHECK-NOT: slice_index_fail
1414
let d = &s.data[s.position..s.position + n];
1515
s.position += n;
1616
return d;
@@ -19,6 +19,6 @@ pub fn slice_no_index_order<'a>(s: &'a mut S1, n: usize) -> &'a [u8] {
1919
// CHECK-LABEL: @test_check
2020
#[no_mangle]
2121
pub fn test_check<'a>(s: &'a mut S1, x: usize, y: usize) -> &'a [u8] {
22-
// CHECK: slice_index_order_fail
22+
// CHECK: slice_index_fail
2323
&s.data[x..y]
2424
}

tests/codegen-llvm/issues/issue-27130.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
#[no_mangle]
77
pub fn trim_in_place(a: &mut &[u8]) {
88
while a.first() == Some(&42) {
9-
// CHECK-NOT: slice_index_order_fail
9+
// CHECK-NOT: slice_index_fail
1010
*a = &a[1..];
1111
}
1212
}
@@ -15,7 +15,7 @@ pub fn trim_in_place(a: &mut &[u8]) {
1515
#[no_mangle]
1616
pub fn trim_in_place2(a: &mut &[u8]) {
1717
while let Some(&42) = a.first() {
18-
// CHECK-NOT: slice_index_order_fail
18+
// CHECK-NOT: slice_index_fail
1919
*a = &a[2..];
2020
}
2121
}

0 commit comments

Comments
 (0)