@@ -34,36 +34,41 @@ where
34
34
#[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
35
35
#[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
36
36
#[ 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`.
50
67
const_panic ! (
51
68
"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}" ,
66
70
end: usize ,
71
+ len: usize ,
67
72
)
68
73
}
69
74
@@ -327,7 +332,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
327
332
// SAFETY: `self` is checked to be valid and in bounds above.
328
333
unsafe { & * get_offset_len_noubcheck ( slice, self . start ( ) , self . len ( ) ) }
329
334
} else {
330
- slice_end_index_len_fail ( self . end ( ) , slice. len ( ) )
335
+ slice_index_fail ( self . start ( ) , self . end ( ) , slice. len ( ) )
331
336
}
332
337
}
333
338
@@ -337,7 +342,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
337
342
// SAFETY: `self` is checked to be valid and in bounds above.
338
343
unsafe { & mut * get_offset_len_mut_noubcheck ( slice, self . start ( ) , self . len ( ) ) }
339
344
} else {
340
- slice_end_index_len_fail ( self . end ( ) , slice. len ( ) )
345
+ slice_index_fail ( self . start ( ) , self . end ( ) , slice. len ( ) )
341
346
}
342
347
}
343
348
}
@@ -422,26 +427,27 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
422
427
#[ inline( always) ]
423
428
fn index ( self , slice : & [ T ] ) -> & [ T ] {
424
429
// 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 ( ) )
430
437
}
431
- // SAFETY: `self` is checked to be valid and in bounds above.
432
- unsafe { & * get_offset_len_noubcheck ( slice, self . start , new_len) }
433
438
}
434
439
435
440
#[ inline]
436
441
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 ( ) )
442
450
}
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) }
445
451
}
446
452
}
447
453
@@ -553,7 +559,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
553
559
#[ inline]
554
560
fn index ( self , slice : & [ T ] ) -> & [ T ] {
555
561
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 ( ) )
557
563
}
558
564
// SAFETY: `self` is checked to be valid and in bounds above.
559
565
unsafe { & * self . get_unchecked ( slice) }
@@ -562,7 +568,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
562
568
#[ inline]
563
569
fn index_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
564
570
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 ( ) )
566
572
}
567
573
// SAFETY: `self` is checked to be valid and in bounds above.
568
574
unsafe { & mut * self . get_unchecked_mut ( slice) }
@@ -678,15 +684,15 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
678
684
#[ inline]
679
685
fn index ( self , slice : & [ T ] ) -> & [ T ] {
680
686
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 ( ) )
682
688
}
683
689
self . into_slice_range ( ) . index ( slice)
684
690
}
685
691
686
692
#[ inline]
687
693
fn index_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
688
694
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 ( ) )
690
696
}
691
697
self . into_slice_range ( ) . index_mut ( slice)
692
698
}
@@ -840,22 +846,22 @@ where
840
846
let len = bounds. end ;
841
847
842
848
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) ,
844
850
// Cannot overflow because `end < len` implies `end < usize::MAX`.
845
851
ops:: Bound :: Included ( & end) => end + 1 ,
846
852
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) ,
848
854
ops:: Bound :: Excluded ( & end) => end,
849
855
850
856
ops:: Bound :: Unbounded => len,
851
857
} ;
852
858
853
859
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 ) ,
855
861
// Cannot overflow because `start < end` implies `start < usize::MAX`.
856
862
ops:: Bound :: Excluded ( & start) => start + 1 ,
857
863
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 ) ,
859
865
ops:: Bound :: Included ( & start) => start,
860
866
861
867
ops:: Bound :: Unbounded => 0 ,
@@ -985,22 +991,22 @@ pub(crate) fn into_slice_range(
985
991
( start, end) : ( ops:: Bound < usize > , ops:: Bound < usize > ) ,
986
992
) -> ops:: Range < usize > {
987
993
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) ,
989
995
// Cannot overflow because `end < len` implies `end < usize::MAX`.
990
996
ops:: Bound :: Included ( end) => end + 1 ,
991
997
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) ,
993
999
ops:: Bound :: Excluded ( end) => end,
994
1000
995
1001
ops:: Bound :: Unbounded => len,
996
1002
} ;
997
1003
998
1004
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 ) ,
1000
1006
// Cannot overflow because `start < end` implies `start < usize::MAX`.
1001
1007
ops:: Bound :: Excluded ( start) => start + 1 ,
1002
1008
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 ) ,
1004
1010
ops:: Bound :: Included ( start) => start,
1005
1011
1006
1012
ops:: Bound :: Unbounded => 0 ,
0 commit comments