1use crate::intrinsics::slice_get_unchecked;
4#[cfg(not(feature = "ferrocene_certified"))]
5use crate::marker::Destruct;
6use crate::panic::const_panic;
7use crate::ub_checks::assert_unsafe_precondition;
8#[cfg(not(feature = "ferrocene_certified"))]
9use crate::{ops, range};
10
11#[cfg(feature = "ferrocene_certified")]
13#[rustfmt::skip]
14use crate::ops;
15
16#[stable(feature = "rust1", since = "1.0.0")]
17#[rustc_const_unstable(feature = "const_index", issue = "143775")]
18impl<T, I> const ops::Index<I> for [T]
19where
20 I: [const] SliceIndex<[T]>,
21{
22 type Output = I::Output;
23
24 #[inline(always)]
25 fn index(&self, index: I) -> &I::Output {
26 index.index(self)
27 }
28}
29
30#[stable(feature = "rust1", since = "1.0.0")]
31#[rustc_const_unstable(feature = "const_index", issue = "143775")]
32impl<T, I> const ops::IndexMut<I> for [T]
33where
34 I: [const] SliceIndex<[T]>,
35{
36 #[inline(always)]
37 fn index_mut(&mut self, index: I) -> &mut I::Output {
38 index.index_mut(self)
39 }
40}
41
42#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
43#[cfg_attr(panic = "immediate-abort", inline)]
44#[track_caller]
45const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
46 if start > len {
47 const_panic!(
48 "slice start index is out of range for slice",
49 "range start index {start} out of range for slice of length {len}",
50 start: usize,
51 len: usize,
52 )
53 }
54
55 if end > len {
56 const_panic!(
57 "slice end index is out of range for slice",
58 "range end index {end} out of range for slice of length {len}",
59 end: usize,
60 len: usize,
61 )
62 }
63
64 if start > end {
65 const_panic!(
66 "slice index start is larger than end",
67 "slice index starts at {start} but ends at {end}",
68 start: usize,
69 end: usize,
70 )
71 }
72
73 const_panic!(
76 "slice end index is out of range for slice",
77 "range end index {end} out of range for slice of length {len}",
78 end: usize,
79 len: usize,
80 )
81}
82
83#[inline(always)]
89const unsafe fn get_offset_len_noubcheck<T>(
90 ptr: *const [T],
91 offset: usize,
92 len: usize,
93) -> *const [T] {
94 let ptr = ptr as *const T;
95 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
97 crate::intrinsics::aggregate_raw_ptr(ptr, len)
98}
99
100#[inline(always)]
101const unsafe fn get_offset_len_mut_noubcheck<T>(
102 ptr: *mut [T],
103 offset: usize,
104 len: usize,
105) -> *mut [T] {
106 let ptr = ptr as *mut T;
107 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
109 crate::intrinsics::aggregate_raw_ptr(ptr, len)
110}
111
112mod private_slice_index {
113 #[cfg(not(feature = "ferrocene_certified"))]
114 use super::{ops, range};
115
116 #[cfg(feature = "ferrocene_certified")]
118 #[rustfmt::skip]
119 use super::ops;
120
121 #[stable(feature = "slice_get_slice", since = "1.28.0")]
122 pub trait Sealed {}
123
124 #[stable(feature = "slice_get_slice", since = "1.28.0")]
125 impl Sealed for usize {}
126 #[stable(feature = "slice_get_slice", since = "1.28.0")]
127 impl Sealed for ops::Range<usize> {}
128 #[stable(feature = "slice_get_slice", since = "1.28.0")]
129 impl Sealed for ops::RangeTo<usize> {}
130 #[stable(feature = "slice_get_slice", since = "1.28.0")]
131 impl Sealed for ops::RangeFrom<usize> {}
132 #[stable(feature = "slice_get_slice", since = "1.28.0")]
133 impl Sealed for ops::RangeFull {}
134 #[stable(feature = "slice_get_slice", since = "1.28.0")]
135 impl Sealed for ops::RangeInclusive<usize> {}
136 #[stable(feature = "slice_get_slice", since = "1.28.0")]
137 impl Sealed for ops::RangeToInclusive<usize> {}
138 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
139 impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
140
141 #[unstable(feature = "new_range_api", issue = "125687")]
142 #[cfg(not(feature = "ferrocene_certified"))]
143 impl Sealed for range::Range<usize> {}
144 #[unstable(feature = "new_range_api", issue = "125687")]
145 #[cfg(not(feature = "ferrocene_certified"))]
146 impl Sealed for range::RangeInclusive<usize> {}
147 #[unstable(feature = "new_range_api", issue = "125687")]
148 #[cfg(not(feature = "ferrocene_certified"))]
149 impl Sealed for range::RangeToInclusive<usize> {}
150 #[unstable(feature = "new_range_api", issue = "125687")]
151 #[cfg(not(feature = "ferrocene_certified"))]
152 impl Sealed for range::RangeFrom<usize> {}
153
154 impl Sealed for ops::IndexRange {}
155}
156
157#[stable(feature = "slice_get_slice", since = "1.28.0")]
162#[rustc_diagnostic_item = "SliceIndex"]
163#[rustc_on_unimplemented(
164 on(T = "str", label = "string indices are ranges of `usize`",),
165 on(
166 all(any(T = "str", T = "&str", T = "alloc::string::String"), Self = "{integer}"),
167 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
168 for more information, see chapter 8 in The Book: \
169 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
170 ),
171 message = "the type `{T}` cannot be indexed by `{Self}`",
172 label = "slice indices are of type `usize` or ranges of `usize`"
173)]
174#[const_trait] #[rustc_const_unstable(feature = "const_index", issue = "143775")]
176pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
177 #[stable(feature = "slice_get_slice", since = "1.28.0")]
179 type Output: ?Sized;
180
181 #[unstable(feature = "slice_index_methods", issue = "none")]
184 fn get(self, slice: &T) -> Option<&Self::Output>;
185
186 #[unstable(feature = "slice_index_methods", issue = "none")]
189 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
190
191 #[unstable(feature = "slice_index_methods", issue = "none")]
199 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
200
201 #[unstable(feature = "slice_index_methods", issue = "none")]
209 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
210
211 #[unstable(feature = "slice_index_methods", issue = "none")]
214 #[track_caller]
215 fn index(self, slice: &T) -> &Self::Output;
216
217 #[unstable(feature = "slice_index_methods", issue = "none")]
220 #[track_caller]
221 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
222}
223
224#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
226#[rustc_const_unstable(feature = "const_index", issue = "143775")]
227unsafe impl<T> const SliceIndex<[T]> for usize {
228 type Output = T;
229
230 #[inline]
231 fn get(self, slice: &[T]) -> Option<&T> {
232 if self < slice.len() {
233 unsafe { Some(slice_get_unchecked(slice, self)) }
235 } else {
236 None
237 }
238 }
239
240 #[inline]
241 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
242 if self < slice.len() {
243 unsafe { Some(slice_get_unchecked(slice, self)) }
245 } else {
246 None
247 }
248 }
249
250 #[inline]
251 #[track_caller]
252 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
253 assert_unsafe_precondition!(
254 check_language_ub, "slice::get_unchecked requires that the index is within the slice",
256 (this: usize = self, len: usize = slice.len()) => this < len
257 );
258 unsafe {
263 crate::intrinsics::assume(self < slice.len());
266 slice_get_unchecked(slice, self)
267 }
268 }
269
270 #[inline]
271 #[track_caller]
272 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
273 assert_unsafe_precondition!(
274 check_library_ub,
275 "slice::get_unchecked_mut requires that the index is within the slice",
276 (this: usize = self, len: usize = slice.len()) => this < len
277 );
278 unsafe { slice_get_unchecked(slice, self) }
280 }
281
282 #[inline]
283 fn index(self, slice: &[T]) -> &T {
284 &(*slice)[self]
286 }
287
288 #[inline]
289 fn index_mut(self, slice: &mut [T]) -> &mut T {
290 &mut (*slice)[self]
292 }
293}
294
295#[rustc_const_unstable(feature = "const_index", issue = "143775")]
298unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
299 type Output = [T];
300
301 #[inline]
302 fn get(self, slice: &[T]) -> Option<&[T]> {
303 if self.end() <= slice.len() {
304 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
306 } else {
307 None
308 }
309 }
310
311 #[inline]
312 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
313 if self.end() <= slice.len() {
314 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
316 } else {
317 None
318 }
319 }
320
321 #[inline]
322 #[track_caller]
323 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
324 assert_unsafe_precondition!(
325 check_library_ub,
326 "slice::get_unchecked requires that the index is within the slice",
327 (end: usize = self.end(), len: usize = slice.len()) => end <= len
328 );
329 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
334 }
335
336 #[inline]
337 #[track_caller]
338 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
339 assert_unsafe_precondition!(
340 check_library_ub,
341 "slice::get_unchecked_mut requires that the index is within the slice",
342 (end: usize = self.end(), len: usize = slice.len()) => end <= len
343 );
344
345 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
347 }
348
349 #[inline]
350 fn index(self, slice: &[T]) -> &[T] {
351 if self.end() <= slice.len() {
352 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
354 } else {
355 slice_index_fail(self.start(), self.end(), slice.len())
356 }
357 }
358
359 #[inline]
360 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
361 if self.end() <= slice.len() {
362 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
364 } else {
365 slice_index_fail(self.start(), self.end(), slice.len())
366 }
367 }
368}
369
370#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
374#[rustc_const_unstable(feature = "const_index", issue = "143775")]
375unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
376 type Output = [T];
377
378 #[inline]
379 fn get(self, slice: &[T]) -> Option<&[T]> {
380 if let Some(new_len) = usize::checked_sub(self.end, self.start)
382 && self.end <= slice.len()
383 {
384 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
386 } else {
387 None
388 }
389 }
390
391 #[inline]
392 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
393 if let Some(new_len) = usize::checked_sub(self.end, self.start)
394 && self.end <= slice.len()
395 {
396 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
398 } else {
399 None
400 }
401 }
402
403 #[inline]
404 #[track_caller]
405 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
406 assert_unsafe_precondition!(
407 check_library_ub,
408 "slice::get_unchecked requires that the range is within the slice",
409 (
410 start: usize = self.start,
411 end: usize = self.end,
412 len: usize = slice.len()
413 ) => end >= start && end <= len
414 );
415
416 unsafe {
421 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
424 get_offset_len_noubcheck(slice, self.start, new_len)
425 }
426 }
427
428 #[inline]
429 #[track_caller]
430 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
431 assert_unsafe_precondition!(
432 check_library_ub,
433 "slice::get_unchecked_mut requires that the range is within the slice",
434 (
435 start: usize = self.start,
436 end: usize = self.end,
437 len: usize = slice.len()
438 ) => end >= start && end <= len
439 );
440 unsafe {
442 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
443 get_offset_len_mut_noubcheck(slice, self.start, new_len)
444 }
445 }
446
447 #[inline(always)]
448 fn index(self, slice: &[T]) -> &[T] {
449 if let Some(new_len) = usize::checked_sub(self.end, self.start)
451 && self.end <= slice.len()
452 {
453 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
455 } else {
456 slice_index_fail(self.start, self.end, slice.len())
457 }
458 }
459
460 #[inline]
461 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
462 if let Some(new_len) = usize::checked_sub(self.end, self.start)
464 && self.end <= slice.len()
465 {
466 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
468 } else {
469 slice_index_fail(self.start, self.end, slice.len())
470 }
471 }
472}
473
474#[unstable(feature = "new_range_api", issue = "125687")]
475#[rustc_const_unstable(feature = "const_index", issue = "143775")]
476#[cfg(not(feature = "ferrocene_certified"))]
477unsafe impl<T> const SliceIndex<[T]> for range::Range<usize> {
478 type Output = [T];
479
480 #[inline]
481 fn get(self, slice: &[T]) -> Option<&[T]> {
482 ops::Range::from(self).get(slice)
483 }
484
485 #[inline]
486 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
487 ops::Range::from(self).get_mut(slice)
488 }
489
490 #[inline]
491 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
492 unsafe { ops::Range::from(self).get_unchecked(slice) }
494 }
495
496 #[inline]
497 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
498 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
500 }
501
502 #[inline(always)]
503 fn index(self, slice: &[T]) -> &[T] {
504 ops::Range::from(self).index(slice)
505 }
506
507 #[inline]
508 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
509 ops::Range::from(self).index_mut(slice)
510 }
511}
512
513#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
515#[rustc_const_unstable(feature = "const_index", issue = "143775")]
516unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
517 type Output = [T];
518
519 #[inline]
520 fn get(self, slice: &[T]) -> Option<&[T]> {
521 (0..self.end).get(slice)
522 }
523
524 #[inline]
525 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
526 (0..self.end).get_mut(slice)
527 }
528
529 #[inline]
530 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
531 unsafe { (0..self.end).get_unchecked(slice) }
533 }
534
535 #[inline]
536 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
537 unsafe { (0..self.end).get_unchecked_mut(slice) }
539 }
540
541 #[inline(always)]
542 fn index(self, slice: &[T]) -> &[T] {
543 (0..self.end).index(slice)
544 }
545
546 #[inline]
547 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
548 (0..self.end).index_mut(slice)
549 }
550}
551
552#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
554#[rustc_const_unstable(feature = "const_index", issue = "143775")]
555unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
556 type Output = [T];
557
558 #[inline]
559 fn get(self, slice: &[T]) -> Option<&[T]> {
560 (self.start..slice.len()).get(slice)
561 }
562
563 #[inline]
564 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
565 (self.start..slice.len()).get_mut(slice)
566 }
567
568 #[inline]
569 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
570 unsafe { (self.start..slice.len()).get_unchecked(slice) }
572 }
573
574 #[inline]
575 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
576 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
578 }
579
580 #[inline]
581 fn index(self, slice: &[T]) -> &[T] {
582 if self.start > slice.len() {
583 slice_index_fail(self.start, slice.len(), slice.len())
584 }
585 unsafe {
587 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
588 &*get_offset_len_noubcheck(slice, self.start, new_len)
589 }
590 }
591
592 #[inline]
593 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
594 if self.start > slice.len() {
595 slice_index_fail(self.start, slice.len(), slice.len())
596 }
597 unsafe {
599 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
600 &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)
601 }
602 }
603}
604
605#[unstable(feature = "new_range_api", issue = "125687")]
606#[rustc_const_unstable(feature = "const_index", issue = "143775")]
607#[cfg(not(feature = "ferrocene_certified"))]
608unsafe impl<T> const SliceIndex<[T]> for range::RangeFrom<usize> {
609 type Output = [T];
610
611 #[inline]
612 fn get(self, slice: &[T]) -> Option<&[T]> {
613 ops::RangeFrom::from(self).get(slice)
614 }
615
616 #[inline]
617 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
618 ops::RangeFrom::from(self).get_mut(slice)
619 }
620
621 #[inline]
622 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
623 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
625 }
626
627 #[inline]
628 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
629 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
631 }
632
633 #[inline]
634 fn index(self, slice: &[T]) -> &[T] {
635 ops::RangeFrom::from(self).index(slice)
636 }
637
638 #[inline]
639 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
640 ops::RangeFrom::from(self).index_mut(slice)
641 }
642}
643
644#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
645#[rustc_const_unstable(feature = "const_index", issue = "143775")]
646unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
647 type Output = [T];
648
649 #[inline]
650 fn get(self, slice: &[T]) -> Option<&[T]> {
651 Some(slice)
652 }
653
654 #[inline]
655 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
656 Some(slice)
657 }
658
659 #[inline]
660 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
661 slice
662 }
663
664 #[inline]
665 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
666 slice
667 }
668
669 #[inline]
670 fn index(self, slice: &[T]) -> &[T] {
671 slice
672 }
673
674 #[inline]
675 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
676 slice
677 }
678}
679
680#[stable(feature = "inclusive_range", since = "1.26.0")]
685#[rustc_const_unstable(feature = "const_index", issue = "143775")]
686unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
687 type Output = [T];
688
689 #[inline]
690 fn get(self, slice: &[T]) -> Option<&[T]> {
691 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
692 }
693
694 #[inline]
695 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
696 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
697 }
698
699 #[inline]
700 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
701 unsafe { self.into_slice_range().get_unchecked(slice) }
703 }
704
705 #[inline]
706 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
707 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
709 }
710
711 #[inline]
712 fn index(self, slice: &[T]) -> &[T] {
713 let Self { mut start, mut end, exhausted } = self;
714 let len = slice.len();
715 if end < len {
716 end = end + 1;
717 start = if exhausted { end } else { start };
718 if let Some(new_len) = usize::checked_sub(end, start) {
719 unsafe { return &*get_offset_len_noubcheck(slice, start, new_len) }
721 }
722 }
723 slice_index_fail(start, end, slice.len())
724 }
725
726 #[inline]
727 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
728 let Self { mut start, mut end, exhausted } = self;
729 let len = slice.len();
730 if end < len {
731 end = end + 1;
732 start = if exhausted { end } else { start };
733 if let Some(new_len) = usize::checked_sub(end, start) {
734 unsafe { return &mut *get_offset_len_mut_noubcheck(slice, start, new_len) }
736 }
737 }
738 slice_index_fail(start, end, slice.len())
739 }
740}
741
742#[unstable(feature = "new_range_api", issue = "125687")]
743#[rustc_const_unstable(feature = "const_index", issue = "143775")]
744#[cfg(not(feature = "ferrocene_certified"))]
745unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
746 type Output = [T];
747
748 #[inline]
749 fn get(self, slice: &[T]) -> Option<&[T]> {
750 ops::RangeInclusive::from(self).get(slice)
751 }
752
753 #[inline]
754 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
755 ops::RangeInclusive::from(self).get_mut(slice)
756 }
757
758 #[inline]
759 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
760 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
762 }
763
764 #[inline]
765 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
766 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
768 }
769
770 #[inline]
771 fn index(self, slice: &[T]) -> &[T] {
772 ops::RangeInclusive::from(self).index(slice)
773 }
774
775 #[inline]
776 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
777 ops::RangeInclusive::from(self).index_mut(slice)
778 }
779}
780
781#[stable(feature = "inclusive_range", since = "1.26.0")]
783#[rustc_const_unstable(feature = "const_index", issue = "143775")]
784unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
785 type Output = [T];
786
787 #[inline]
788 fn get(self, slice: &[T]) -> Option<&[T]> {
789 (0..=self.end).get(slice)
790 }
791
792 #[inline]
793 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
794 (0..=self.end).get_mut(slice)
795 }
796
797 #[inline]
798 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
799 unsafe { (0..=self.end).get_unchecked(slice) }
801 }
802
803 #[inline]
804 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
805 unsafe { (0..=self.end).get_unchecked_mut(slice) }
807 }
808
809 #[inline]
810 fn index(self, slice: &[T]) -> &[T] {
811 (0..=self.end).index(slice)
812 }
813
814 #[inline]
815 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
816 (0..=self.end).index_mut(slice)
817 }
818}
819
820#[stable(feature = "inclusive_range", since = "1.26.0")]
822#[rustc_const_unstable(feature = "const_index", issue = "143775")]
823#[cfg(not(feature = "ferrocene_certified"))]
824unsafe impl<T> const SliceIndex<[T]> for range::RangeToInclusive<usize> {
825 type Output = [T];
826
827 #[inline]
828 fn get(self, slice: &[T]) -> Option<&[T]> {
829 (0..=self.last).get(slice)
830 }
831
832 #[inline]
833 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
834 (0..=self.last).get_mut(slice)
835 }
836
837 #[inline]
838 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
839 unsafe { (0..=self.last).get_unchecked(slice) }
841 }
842
843 #[inline]
844 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
845 unsafe { (0..=self.last).get_unchecked_mut(slice) }
847 }
848
849 #[inline]
850 fn index(self, slice: &[T]) -> &[T] {
851 (0..=self.last).index(slice)
852 }
853
854 #[inline]
855 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
856 (0..=self.last).index_mut(slice)
857 }
858}
859
860#[track_caller]
922#[unstable(feature = "slice_range", issue = "76393")]
923#[must_use]
924#[rustc_const_unstable(feature = "const_range", issue = "none")]
925#[cfg(not(feature = "ferrocene_certified"))]
926pub const fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
927where
928 R: [const] ops::RangeBounds<usize> + [const] Destruct,
929{
930 let len = bounds.end;
931
932 let end = match range.end_bound() {
933 ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
934 ops::Bound::Included(&end) => end + 1,
936
937 ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
938 ops::Bound::Excluded(&end) => end,
939 ops::Bound::Unbounded => len,
940 };
941
942 let start = match range.start_bound() {
943 ops::Bound::Excluded(&start) if start >= end => slice_index_fail(start, end, len),
944 ops::Bound::Excluded(&start) => start + 1,
946
947 ops::Bound::Included(&start) if start > end => slice_index_fail(start, end, len),
948 ops::Bound::Included(&start) => start,
949
950 ops::Bound::Unbounded => 0,
951 };
952
953 ops::Range { start, end }
954}
955
956#[unstable(feature = "slice_range", issue = "76393")]
987#[must_use]
988#[cfg(not(feature = "ferrocene_certified"))]
989pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
990where
991 R: ops::RangeBounds<usize>,
992{
993 let len = bounds.end;
994
995 let start = match range.start_bound() {
996 ops::Bound::Included(&start) => start,
997 ops::Bound::Excluded(start) => start.checked_add(1)?,
998 ops::Bound::Unbounded => 0,
999 };
1000
1001 let end = match range.end_bound() {
1002 ops::Bound::Included(end) => end.checked_add(1)?,
1003 ops::Bound::Excluded(&end) => end,
1004 ops::Bound::Unbounded => len,
1005 };
1006
1007 if start > end || end > len { None } else { Some(ops::Range { start, end }) }
1008}
1009
1010pub(crate) const fn into_range_unchecked(
1013 len: usize,
1014 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1015) -> ops::Range<usize> {
1016 use ops::Bound;
1017 let start = match start {
1018 Bound::Included(i) => i,
1019 Bound::Excluded(i) => i + 1,
1020 Bound::Unbounded => 0,
1021 };
1022 let end = match end {
1023 Bound::Included(i) => i + 1,
1024 Bound::Excluded(i) => i,
1025 Bound::Unbounded => len,
1026 };
1027 start..end
1028}
1029
1030#[rustc_const_unstable(feature = "const_range", issue = "none")]
1033pub(crate) const fn into_range(
1034 len: usize,
1035 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1036) -> Option<ops::Range<usize>> {
1037 use ops::Bound;
1038 let start = match start {
1039 Bound::Included(start) => start,
1040 Bound::Excluded(start) => start.checked_add(1)?,
1041 Bound::Unbounded => 0,
1042 };
1043
1044 let end = match end {
1045 Bound::Included(end) => end.checked_add(1)?,
1046 Bound::Excluded(end) => end,
1047 Bound::Unbounded => len,
1048 };
1049
1050 Some(start..end)
1054}
1055
1056pub(crate) fn into_slice_range(
1059 len: usize,
1060 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1061) -> ops::Range<usize> {
1062 let end = match end {
1063 ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
1064 ops::Bound::Included(end) => end + 1,
1066
1067 ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
1068 ops::Bound::Excluded(end) => end,
1069
1070 ops::Bound::Unbounded => len,
1071 };
1072
1073 let start = match start {
1074 ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
1075 ops::Bound::Excluded(start) => start + 1,
1077
1078 ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
1079 ops::Bound::Included(start) => start,
1080
1081 ops::Bound::Unbounded => 0,
1082 };
1083
1084 start..end
1085}
1086
1087#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1088unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1089 type Output = [T];
1090
1091 #[inline]
1092 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1093 into_range(slice.len(), self)?.get(slice)
1094 }
1095
1096 #[inline]
1097 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1098 into_range(slice.len(), self)?.get_mut(slice)
1099 }
1100
1101 #[inline]
1102 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1103 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1105 }
1106
1107 #[inline]
1108 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1109 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1111 }
1112
1113 #[inline]
1114 fn index(self, slice: &[T]) -> &Self::Output {
1115 into_slice_range(slice.len(), self).index(slice)
1116 }
1117
1118 #[inline]
1119 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1120 into_slice_range(slice.len(), self).index_mut(slice)
1121 }
1122}