Skip to content

Commit c5baa68

Browse files
committed
Optimize std::slice::range
Same reasoning as previous commit.
1 parent ec8b641 commit c5baa68

File tree

1 file changed

+37
-20
lines changed

1 file changed

+37
-20
lines changed

library/core/src/slice/index.rs

Lines changed: 37 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -933,6 +933,7 @@ where
933933

934934
ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
935935
ops::Bound::Excluded(&end) => end,
936+
936937
ops::Bound::Unbounded => len,
937938
};
938939

@@ -988,19 +989,29 @@ where
988989
{
989990
let len = bounds.end;
990991

991-
let start = match range.start_bound() {
992-
ops::Bound::Included(&start) => start,
993-
ops::Bound::Excluded(start) => start.checked_add(1)?,
994-
ops::Bound::Unbounded => 0,
995-
};
996-
997992
let end = match range.end_bound() {
998-
ops::Bound::Included(end) => end.checked_add(1)?,
993+
ops::Bound::Included(&end) if end >= len => return None,
994+
// Cannot overflow because `end < len` implies `end < usize::MAX`.
995+
ops::Bound::Included(end) => end + 1,
996+
997+
ops::Bound::Excluded(&end) if end > len => return None,
999998
ops::Bound::Excluded(&end) => end,
999+
10001000
ops::Bound::Unbounded => len,
10011001
};
10021002

1003-
if start > end || end > len { None } else { Some(ops::Range { start, end }) }
1003+
let start = match range.start_bound() {
1004+
ops::Bound::Excluded(&start) if start >= end => return None,
1005+
// Cannot overflow because `start < end` implies `start < usize::MAX`.
1006+
ops::Bound::Excluded(&start) => start + 1,
1007+
1008+
ops::Bound::Included(&start) if start > end => return None,
1009+
ops::Bound::Included(&start) => start,
1010+
1011+
ops::Bound::Unbounded => 0,
1012+
};
1013+
1014+
Some(ops::Range { start, end })
10041015
}
10051016

10061017
/// Converts a pair of `ops::Bound`s into `ops::Range` without performing any
@@ -1029,21 +1040,27 @@ pub(crate) fn into_range(
10291040
len: usize,
10301041
(start, end): (ops::Bound<usize>, ops::Bound<usize>),
10311042
) -> Option<ops::Range<usize>> {
1032-
use ops::Bound;
1033-
let start = match start {
1034-
Bound::Included(start) => start,
1035-
Bound::Excluded(start) => start.checked_add(1)?,
1036-
Bound::Unbounded => 0,
1037-
};
1038-
10391043
let end = match end {
1040-
Bound::Included(end) => end.checked_add(1)?,
1041-
Bound::Excluded(end) => end,
1042-
Bound::Unbounded => len,
1044+
ops::Bound::Included(end) if end >= len => return None,
1045+
// Cannot overflow because `end < len` implies `end < usize::MAX`.
1046+
ops::Bound::Included(end) => end + 1,
1047+
1048+
ops::Bound::Excluded(end) if end > len => return None,
1049+
ops::Bound::Excluded(end) => end,
1050+
1051+
ops::Bound::Unbounded => len,
10431052
};
10441053

1045-
// Don't bother with checking `start < end` and `end <= len`
1046-
// since these checks are handled by `Range` impls
1054+
let start = match start {
1055+
ops::Bound::Excluded(start) if start >= end => return None,
1056+
// Cannot overflow because `start < end` implies `start < usize::MAX`.
1057+
ops::Bound::Excluded(start) => start + 1,
1058+
1059+
ops::Bound::Included(start) if start > end => return None,
1060+
ops::Bound::Included(start) => start,
1061+
1062+
ops::Bound::Unbounded => 0,
1063+
};
10471064

10481065
Some(start..end)
10491066
}

0 commit comments

Comments
 (0)