@@ -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,
@@ -853,28 +839,27 @@ where
853
839
{
854
840
let len = bounds. end ;
855
841
856
- let start = match range. start_bound ( ) {
857
- ops:: Bound :: Included ( & start) => start,
858
- ops:: Bound :: Excluded ( start) => {
859
- start. checked_add ( 1 ) . unwrap_or_else ( || slice_start_index_overflow_fail ( ) )
860
- }
861
- ops:: Bound :: Unbounded => 0 ,
862
- } ;
863
-
864
842
let end = match range. end_bound ( ) {
865
- ops:: Bound :: Included ( end) => {
866
- end. checked_add ( 1 ) . unwrap_or_else ( || slice_end_index_overflow_fail ( ) )
867
- }
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) ,
868
848
ops:: Bound :: Excluded ( & end) => end,
849
+
869
850
ops:: Bound :: Unbounded => len,
870
851
} ;
871
852
872
- if start > end {
873
- slice_index_order_fail ( start, end) ;
874
- }
875
- if end > len {
876
- slice_end_index_len_fail ( end, len) ;
877
- }
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
+ } ;
878
863
879
864
ops:: Range { start, end }
880
865
}
@@ -917,19 +902,29 @@ where
917
902
{
918
903
let len = bounds. end ;
919
904
920
- let start = match range. start_bound ( ) {
921
- ops:: Bound :: Included ( & start) => start,
922
- ops:: Bound :: Excluded ( start) => start. checked_add ( 1 ) ?,
923
- ops:: Bound :: Unbounded => 0 ,
924
- } ;
925
-
926
905
let end = match range. end_bound ( ) {
927
- 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 ,
928
911
ops:: Bound :: Excluded ( & end) => end,
912
+
929
913
ops:: Bound :: Unbounded => len,
930
914
} ;
931
915
932
- 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 } )
933
928
}
934
929
935
930
/// Converts a pair of `ops::Bound`s into `ops::Range` without performing any
@@ -958,21 +953,27 @@ pub(crate) fn into_range(
958
953
len : usize ,
959
954
( start, end) : ( ops:: Bound < usize > , ops:: Bound < usize > ) ,
960
955
) -> Option < ops:: Range < usize > > {
961
- use ops:: Bound ;
962
- let start = match start {
963
- Bound :: Included ( start) => start,
964
- Bound :: Excluded ( start) => start. checked_add ( 1 ) ?,
965
- Bound :: Unbounded => 0 ,
966
- } ;
967
-
968
956
let end = match end {
969
- Bound :: Included ( end) => end. checked_add ( 1 ) ?,
970
- Bound :: Excluded ( end) => end,
971
- 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,
972
965
} ;
973
966
974
- // Don't bother with checking `start < end` and `end <= len`
975
- // 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
+ } ;
976
977
977
978
Some ( start..end)
978
979
}
@@ -983,25 +984,27 @@ pub(crate) fn into_slice_range(
983
984
len : usize ,
984
985
( start, end) : ( ops:: Bound < usize > , ops:: Bound < usize > ) ,
985
986
) -> ops:: Range < usize > {
986
- use ops:: Bound ;
987
- let start = match start {
988
- Bound :: Included ( start) => start,
989
- Bound :: Excluded ( start) => {
990
- start. checked_add ( 1 ) . unwrap_or_else ( || slice_start_index_overflow_fail ( ) )
991
- }
992
- Bound :: Unbounded => 0 ,
993
- } ;
994
-
995
987
let end = match end {
996
- Bound :: Included ( end) => {
997
- end. checked_add ( 1 ) . unwrap_or_else ( || slice_end_index_overflow_fail ( ) )
998
- }
999
- Bound :: Excluded ( end) => end,
1000
- 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,
1001
996
} ;
1002
997
1003
- // Don't bother with checking `start < end` and `end <= len`
1004
- // 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
+ } ;
1005
1008
1006
1009
start..end
1007
1010
}
0 commit comments