bump_scope/polyfill/
slice.rs

1use core::ops;
2
3pub(crate) use core::slice::*;
4
5#[cold]
6#[inline(never)]
7#[track_caller]
8pub(crate) const fn slice_start_index_overflow_fail() -> ! {
9    panic!("attempted to index slice from after maximum usize");
10}
11
12#[cold]
13#[inline(never)]
14#[track_caller]
15pub(crate) const fn slice_end_index_overflow_fail() -> ! {
16    panic!("attempted to index slice up to maximum usize");
17}
18
19#[cold]
20#[inline(never)]
21#[track_caller]
22fn slice_index_order_fail(index: usize, end: usize) -> ! {
23    panic!("slice index starts at {index} but ends at {end}");
24}
25
26#[cold]
27#[inline(never)]
28#[track_caller]
29fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
30    panic!("range end index {index} out of range for slice of length {len}")
31}
32
33/// See [`std::slice::range`].
34#[track_caller]
35#[must_use]
36pub(crate) fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
37where
38    R: ops::RangeBounds<usize>,
39{
40    let len = bounds.end;
41
42    let start: ops::Bound<&usize> = range.start_bound();
43    let start = match start {
44        ops::Bound::Included(&start) => start,
45        ops::Bound::Excluded(start) => start.checked_add(1).unwrap_or_else(|| slice_start_index_overflow_fail()),
46        ops::Bound::Unbounded => 0,
47    };
48
49    let end: ops::Bound<&usize> = range.end_bound();
50    let end = match end {
51        ops::Bound::Included(end) => end.checked_add(1).unwrap_or_else(|| slice_end_index_overflow_fail()),
52        ops::Bound::Excluded(&end) => end,
53        ops::Bound::Unbounded => len,
54    };
55
56    if start > end {
57        slice_index_order_fail(start, end);
58    }
59    if end > len {
60        slice_end_index_len_fail(end, len);
61    }
62
63    ops::Range { start, end }
64}