@@ -67,20 +67,6 @@ const fn slice_index_order_fail(index: usize, end: usize) -> ! {
67
67
)
68
68
}
69
69
70
- #[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
71
- #[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
72
- #[ track_caller]
73
- const fn slice_start_index_overflow_fail ( ) -> ! {
74
- panic ! ( "attempted to index slice from after maximum usize" ) ;
75
- }
76
-
77
- #[ cfg_attr( not( feature = "panic_immediate_abort" ) , inline( never) , cold) ]
78
- #[ cfg_attr( feature = "panic_immediate_abort" , inline) ]
79
- #[ track_caller]
80
- const fn slice_end_index_overflow_fail ( ) -> ! {
81
- panic ! ( "attempted to index slice up to maximum usize" ) ;
82
- }
83
-
84
70
// The UbChecks are great for catching bugs in the unsafe methods, but including
85
71
// them in safe indexing is unnecessary and hurts inlining and debug runtime perf.
86
72
// Both the safe and unsafe public methods share these helpers,
@@ -658,7 +644,6 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
658
644
}
659
645
660
646
/// The methods `index` and `index_mut` panic if:
661
- /// - the end of the range is `usize::MAX` or
662
647
/// - the start of the range is greater than the end of the range or
663
648
/// - the end of the range is out of bounds.
664
649
#[ stable( feature = "inclusive_range" , since = "1.26.0" ) ]
@@ -668,12 +653,14 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
668
653
669
654
#[ inline]
670
655
fn get ( self , slice : & [ T ] ) -> Option < & [ T ] > {
671
- if * self . end ( ) == usize:: MAX { None } else { self . into_slice_range ( ) . get ( slice) }
656
+ // `self.into_slice_range()` cannot overflow, because `*self.end() <
657
+ // slice.len()` implies `*self.end() < usize::MAX`.
658
+ if * self . end ( ) >= slice. len ( ) { None } else { self . into_slice_range ( ) . get ( slice) }
672
659
}
673
660
674
661
#[ inline]
675
662
fn get_mut ( self , slice : & mut [ T ] ) -> Option < & mut [ T ] > {
676
- if * self . end ( ) == usize :: MAX { None } else { self . into_slice_range ( ) . get_mut ( slice) }
663
+ if * self . end ( ) >= slice . len ( ) { None } else { self . into_slice_range ( ) . get_mut ( slice) }
677
664
}
678
665
679
666
#[ inline]
@@ -690,16 +677,16 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
690
677
691
678
#[ inline]
692
679
fn index ( self , slice : & [ T ] ) -> & [ T ] {
693
- if * self . end ( ) == usize :: MAX {
694
- slice_end_index_overflow_fail ( ) ;
680
+ if * self . end ( ) >= slice . len ( ) {
681
+ slice_end_index_len_fail ( * self . end ( ) , slice . len ( ) ) ;
695
682
}
696
683
self . into_slice_range ( ) . index ( slice)
697
684
}
698
685
699
686
#[ inline]
700
687
fn index_mut ( self , slice : & mut [ T ] ) -> & mut [ T ] {
701
- if * self . end ( ) == usize :: MAX {
702
- slice_end_index_overflow_fail ( ) ;
688
+ if * self . end ( ) >= slice . len ( ) {
689
+ slice_end_index_len_fail ( * self . end ( ) , slice . len ( ) ) ;
703
690
}
704
691
self . into_slice_range ( ) . index_mut ( slice)
705
692
}
@@ -852,28 +839,27 @@ where
852
839
{
853
840
let len = bounds. end ;
854
841
855
- let start = match range. start_bound ( ) {
856
- ops:: Bound :: Included ( & start) => start,
857
- ops:: Bound :: Excluded ( start) => {
858
- start. checked_add ( 1 ) . unwrap_or_else ( || slice_start_index_overflow_fail ( ) )
859
- }
860
- ops:: Bound :: Unbounded => 0 ,
861
- } ;
862
-
863
842
let end = match range. end_bound ( ) {
864
- ops:: Bound :: Included ( end) => {
865
- end. checked_add ( 1 ) . unwrap_or_else ( || slice_end_index_overflow_fail ( ) )
866
- }
843
+ ops:: Bound :: Included ( & end) if end >= len => slice_end_index_len_fail ( end, len) ,
844
+ // Cannot overflow because `end < len` implies `end < usize::MAX`.
845
+ ops:: Bound :: Included ( & end) => end + 1 ,
846
+
847
+ ops:: Bound :: Excluded ( & end) if end > len => slice_end_index_len_fail ( end, len) ,
867
848
ops:: Bound :: Excluded ( & end) => end,
849
+
868
850
ops:: Bound :: Unbounded => len,
869
851
} ;
870
852
871
- if start > end {
872
- slice_index_order_fail ( start, end) ;
873
- }
874
- if end > len {
875
- slice_end_index_len_fail ( end, len) ;
876
- }
853
+ let start = match range. start_bound ( ) {
854
+ ops:: Bound :: Excluded ( & start) if start >= end => slice_index_order_fail ( start, end) ,
855
+ // Cannot overflow because `start < end` implies `start < usize::MAX`.
856
+ ops:: Bound :: Excluded ( & start) => start + 1 ,
857
+
858
+ ops:: Bound :: Included ( & start) if start > end => slice_index_order_fail ( start, end) ,
859
+ ops:: Bound :: Included ( & start) => start,
860
+
861
+ ops:: Bound :: Unbounded => 0 ,
862
+ } ;
877
863
878
864
ops:: Range { start, end }
879
865
}
@@ -916,19 +902,29 @@ where
916
902
{
917
903
let len = bounds. end ;
918
904
919
- let start = match range. start_bound ( ) {
920
- ops:: Bound :: Included ( & start) => start,
921
- ops:: Bound :: Excluded ( start) => start. checked_add ( 1 ) ?,
922
- ops:: Bound :: Unbounded => 0 ,
923
- } ;
924
-
925
905
let end = match range. end_bound ( ) {
926
- ops:: Bound :: Included ( end) => end. checked_add ( 1 ) ?,
906
+ ops:: Bound :: Included ( & end) if end >= len => return None ,
907
+ // Cannot overflow because `end < len` implies `end < usize::MAX`.
908
+ ops:: Bound :: Included ( end) => end + 1 ,
909
+
910
+ ops:: Bound :: Excluded ( & end) if end > len => return None ,
927
911
ops:: Bound :: Excluded ( & end) => end,
912
+
928
913
ops:: Bound :: Unbounded => len,
929
914
} ;
930
915
931
- if start > end || end > len { None } else { Some ( ops:: Range { start, end } ) }
916
+ let start = match range. start_bound ( ) {
917
+ ops:: Bound :: Excluded ( & start) if start >= end => return None ,
918
+ // Cannot overflow because `start < end` implies `start < usize::MAX`.
919
+ ops:: Bound :: Excluded ( & start) => start + 1 ,
920
+
921
+ ops:: Bound :: Included ( & start) if start > end => return None ,
922
+ ops:: Bound :: Included ( & start) => start,
923
+
924
+ ops:: Bound :: Unbounded => 0 ,
925
+ } ;
926
+
927
+ Some ( ops:: Range { start, end } )
932
928
}
933
929
934
930
/// Converts a pair of `ops::Bound`s into `ops::Range` without performing any
@@ -957,21 +953,27 @@ pub(crate) fn into_range(
957
953
len : usize ,
958
954
( start, end) : ( ops:: Bound < usize > , ops:: Bound < usize > ) ,
959
955
) -> Option < ops:: Range < usize > > {
960
- use ops:: Bound ;
961
- let start = match start {
962
- Bound :: Included ( start) => start,
963
- Bound :: Excluded ( start) => start. checked_add ( 1 ) ?,
964
- Bound :: Unbounded => 0 ,
965
- } ;
966
-
967
956
let end = match end {
968
- Bound :: Included ( end) => end. checked_add ( 1 ) ?,
969
- Bound :: Excluded ( end) => end,
970
- Bound :: Unbounded => len,
957
+ ops:: Bound :: Included ( end) if end >= len => return None ,
958
+ // Cannot overflow because `end < len` implies `end < usize::MAX`.
959
+ ops:: Bound :: Included ( end) => end + 1 ,
960
+
961
+ ops:: Bound :: Excluded ( end) if end > len => return None ,
962
+ ops:: Bound :: Excluded ( end) => end,
963
+
964
+ ops:: Bound :: Unbounded => len,
971
965
} ;
972
966
973
- // Don't bother with checking `start < end` and `end <= len`
974
- // since these checks are handled by `Range` impls
967
+ let start = match start {
968
+ ops:: Bound :: Excluded ( start) if start >= end => return None ,
969
+ // Cannot overflow because `start < end` implies `start < usize::MAX`.
970
+ ops:: Bound :: Excluded ( start) => start + 1 ,
971
+
972
+ ops:: Bound :: Included ( start) if start > end => return None ,
973
+ ops:: Bound :: Included ( start) => start,
974
+
975
+ ops:: Bound :: Unbounded => 0 ,
976
+ } ;
975
977
976
978
Some ( start..end)
977
979
}
@@ -982,25 +984,27 @@ pub(crate) fn into_slice_range(
982
984
len : usize ,
983
985
( start, end) : ( ops:: Bound < usize > , ops:: Bound < usize > ) ,
984
986
) -> ops:: Range < usize > {
985
- use ops:: Bound ;
986
- let start = match start {
987
- Bound :: Included ( start) => start,
988
- Bound :: Excluded ( start) => {
989
- start. checked_add ( 1 ) . unwrap_or_else ( || slice_start_index_overflow_fail ( ) )
990
- }
991
- Bound :: Unbounded => 0 ,
992
- } ;
993
-
994
987
let end = match end {
995
- Bound :: Included ( end) => {
996
- end. checked_add ( 1 ) . unwrap_or_else ( || slice_end_index_overflow_fail ( ) )
997
- }
998
- Bound :: Excluded ( end) => end,
999
- Bound :: Unbounded => len,
988
+ ops:: Bound :: Included ( end) if end >= len => slice_end_index_len_fail ( end, len) ,
989
+ // Cannot overflow because `end < len` implies `end < usize::MAX`.
990
+ ops:: Bound :: Included ( end) => end + 1 ,
991
+
992
+ ops:: Bound :: Excluded ( end) if end > len => slice_end_index_len_fail ( end, len) ,
993
+ ops:: Bound :: Excluded ( end) => end,
994
+
995
+ ops:: Bound :: Unbounded => len,
1000
996
} ;
1001
997
1002
- // Don't bother with checking `start < end` and `end <= len`
1003
- // since these checks are handled by `Range` impls
998
+ let start = match start {
999
+ ops:: Bound :: Excluded ( start) if start >= end => slice_index_order_fail ( start, end) ,
1000
+ // Cannot overflow because `start < end` implies `start < usize::MAX`.
1001
+ ops:: Bound :: Excluded ( start) => start + 1 ,
1002
+
1003
+ ops:: Bound :: Included ( start) if start > end => slice_index_order_fail ( start, end) ,
1004
+ ops:: Bound :: Included ( start) => start,
1005
+
1006
+ ops:: Bound :: Unbounded => 0 ,
1007
+ } ;
1004
1008
1005
1009
start..end
1006
1010
}
0 commit comments