Skip to content

Commit eab010d

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 eab010d

File tree

2 files changed

+51
-46
lines changed

2 files changed

+51
-46
lines changed

library/core/src/slice/index.rs

Lines changed: 50 additions & 45 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
}
@@ -423,10 +428,10 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
423428
fn index(self, slice: &[T]) -> &[T] {
424429
// Using checked_sub is a safe way to get `SubUnchecked` in MIR
425430
let Some(new_len) = usize::checked_sub(self.end, self.start) else {
426-
slice_index_order_fail(self.start, self.end)
431+
slice_index_fail(self.start, self.end, slice.len())
427432
};
428433
if self.end > slice.len() {
429-
slice_end_index_len_fail(self.end, slice.len());
434+
slice_index_fail(self.start, self.end, slice.len())
430435
}
431436
// SAFETY: `self` is checked to be valid and in bounds above.
432437
unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
@@ -435,10 +440,10 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
435440
#[inline]
436441
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
437442
let Some(new_len) = usize::checked_sub(self.end, self.start) else {
438-
slice_index_order_fail(self.start, self.end)
443+
slice_index_fail(self.start, self.end, slice.len())
439444
};
440445
if self.end > slice.len() {
441-
slice_end_index_len_fail(self.end, slice.len());
446+
slice_index_fail(self.start, self.end, slice.len())
442447
}
443448
// SAFETY: `self` is checked to be valid and in bounds above.
444449
unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
@@ -553,7 +558,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
553558
#[inline]
554559
fn index(self, slice: &[T]) -> &[T] {
555560
if self.start > slice.len() {
556-
slice_start_index_len_fail(self.start, slice.len());
561+
slice_index_fail(self.start, slice.len(), slice.len())
557562
}
558563
// SAFETY: `self` is checked to be valid and in bounds above.
559564
unsafe { &*self.get_unchecked(slice) }
@@ -562,7 +567,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
562567
#[inline]
563568
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
564569
if self.start > slice.len() {
565-
slice_start_index_len_fail(self.start, slice.len());
570+
slice_index_fail(self.start, slice.len(), slice.len())
566571
}
567572
// SAFETY: `self` is checked to be valid and in bounds above.
568573
unsafe { &mut *self.get_unchecked_mut(slice) }
@@ -678,15 +683,15 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
678683
#[inline]
679684
fn index(self, slice: &[T]) -> &[T] {
680685
if *self.end() >= slice.len() {
681-
slice_end_index_len_fail(*self.end(), slice.len());
686+
slice_index_fail(self.start, self.end, slice.len())
682687
}
683688
self.into_slice_range().index(slice)
684689
}
685690

686691
#[inline]
687692
fn index_mut(self, slice: &mut [T]) -> &mut [T] {
688693
if *self.end() >= slice.len() {
689-
slice_end_index_len_fail(*self.end(), slice.len());
694+
slice_index_fail(self.start, self.end, slice.len())
690695
}
691696
self.into_slice_range().index_mut(slice)
692697
}
@@ -840,22 +845,22 @@ where
840845
let len = bounds.end;
841846

842847
let end = match range.end_bound() {
843-
ops::Bound::Included(&end) if end >= len => slice_end_index_len_fail(end, len),
848+
ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
844849
// Cannot overflow because `end < len` implies `end < usize::MAX`.
845850
ops::Bound::Included(&end) => end + 1,
846851

847-
ops::Bound::Excluded(&end) if end > len => slice_end_index_len_fail(end, len),
852+
ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
848853
ops::Bound::Excluded(&end) => end,
849854

850855
ops::Bound::Unbounded => len,
851856
};
852857

853858
let start = match range.start_bound() {
854-
ops::Bound::Excluded(&start) if start >= end => slice_index_order_fail(start, end),
859+
ops::Bound::Excluded(&start) if start >= end => slice_index_fail(start, end, len),
855860
// Cannot overflow because `start < end` implies `start < usize::MAX`.
856861
ops::Bound::Excluded(&start) => start + 1,
857862

858-
ops::Bound::Included(&start) if start > end => slice_index_order_fail(start, end),
863+
ops::Bound::Included(&start) if start > end => slice_index_fail(start, end, len),
859864
ops::Bound::Included(&start) => start,
860865

861866
ops::Bound::Unbounded => 0,
@@ -985,22 +990,22 @@ pub(crate) fn into_slice_range(
985990
(start, end): (ops::Bound<usize>, ops::Bound<usize>),
986991
) -> ops::Range<usize> {
987992
let end = match end {
988-
ops::Bound::Included(end) if end >= len => slice_end_index_len_fail(end, len),
993+
ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
989994
// Cannot overflow because `end < len` implies `end < usize::MAX`.
990995
ops::Bound::Included(end) => end + 1,
991996

992-
ops::Bound::Excluded(end) if end > len => slice_end_index_len_fail(end, len),
997+
ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
993998
ops::Bound::Excluded(end) => end,
994999

9951000
ops::Bound::Unbounded => len,
9961001
};
9971002

9981003
let start = match start {
999-
ops::Bound::Excluded(start) if start >= end => slice_index_order_fail(start, end),
1004+
ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
10001005
// Cannot overflow because `start < end` implies `start < usize::MAX`.
10011006
ops::Bound::Excluded(start) => start + 1,
10021007

1003-
ops::Bound::Included(start) if start > end => slice_index_order_fail(start, end),
1008+
ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
10041009
ops::Bound::Included(start) => start,
10051010

10061011
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
}

0 commit comments

Comments
 (0)