@@ -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 ,
0 commit comments