1use crate::intrinsics::slice_get_unchecked;
4use crate::marker::Destruct;
5use crate::panic::const_panic;
6use crate::ub_checks::assert_unsafe_precondition;
7use crate::{ops, range};
8
9#[stable(feature = "rust1", since = "1.0.0")]
10#[rustc_const_unstable(feature = "const_index", issue = "143775")]
11impl<T, I> const ops::Index<I> for [T]
12where
13 I: [const] SliceIndex<[T]>,
14{
15 type Output = I::Output;
16
17 #[inline(always)]
18 fn index(&self, index: I) -> &I::Output {
19 index.index(self)
20 }
21}
22
23#[stable(feature = "rust1", since = "1.0.0")]
24#[rustc_const_unstable(feature = "const_index", issue = "143775")]
25impl<T, I> const ops::IndexMut<I> for [T]
26where
27 I: [const] SliceIndex<[T]>,
28{
29 #[inline(always)]
30 fn index_mut(&mut self, index: I) -> &mut I::Output {
31 index.index_mut(self)
32 }
33}
34
35#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
36#[cfg_attr(panic = "immediate-abort", inline)]
37#[track_caller]
38const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
39 if start > len {
40 const_panic!(
41 "slice start index is out of range for slice",
42 "range start index {start} out of range for slice of length {len}",
43 start: usize,
44 len: usize,
45 )
46 }
47
48 if end > len {
49 const_panic!(
50 "slice end index is out of range for slice",
51 "range end index {end} out of range for slice of length {len}",
52 end: usize,
53 len: usize,
54 )
55 }
56
57 if start > end {
58 const_panic!(
59 "slice index start is larger than end",
60 "slice index starts at {start} but ends at {end}",
61 start: usize,
62 end: usize,
63 )
64 }
65
66 const_panic!(
69 "slice end index is out of range for slice",
70 "range end index {end} out of range for slice of length {len}",
71 end: usize,
72 len: usize,
73 )
74}
75
76#[inline(always)]
82const unsafe fn get_offset_len_noubcheck<T>(
83 ptr: *const [T],
84 offset: usize,
85 len: usize,
86) -> *const [T] {
87 let ptr = ptr as *const T;
88 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
90 crate::intrinsics::aggregate_raw_ptr(ptr, len)
91}
92
93#[inline(always)]
94const unsafe fn get_offset_len_mut_noubcheck<T>(
95 ptr: *mut [T],
96 offset: usize,
97 len: usize,
98) -> *mut [T] {
99 let ptr = ptr as *mut T;
100 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
102 crate::intrinsics::aggregate_raw_ptr(ptr, len)
103}
104
105mod private_slice_index {
106 use super::{ops, range};
107
108 #[stable(feature = "slice_get_slice", since = "1.28.0")]
109 pub trait Sealed {}
110
111 #[stable(feature = "slice_get_slice", since = "1.28.0")]
112 impl Sealed for usize {}
113 #[stable(feature = "slice_get_slice", since = "1.28.0")]
114 impl Sealed for ops::Range<usize> {}
115 #[stable(feature = "slice_get_slice", since = "1.28.0")]
116 impl Sealed for ops::RangeTo<usize> {}
117 #[stable(feature = "slice_get_slice", since = "1.28.0")]
118 impl Sealed for ops::RangeFrom<usize> {}
119 #[stable(feature = "slice_get_slice", since = "1.28.0")]
120 impl Sealed for ops::RangeFull {}
121 #[stable(feature = "slice_get_slice", since = "1.28.0")]
122 impl Sealed for ops::RangeInclusive<usize> {}
123 #[stable(feature = "slice_get_slice", since = "1.28.0")]
124 impl Sealed for ops::RangeToInclusive<usize> {}
125 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
126 impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
127
128 #[unstable(feature = "new_range_api", issue = "125687")]
129 impl Sealed for range::Range<usize> {}
130 #[unstable(feature = "new_range_api", issue = "125687")]
131 impl Sealed for range::RangeInclusive<usize> {}
132 #[unstable(feature = "new_range_api", issue = "125687")]
133 impl Sealed for range::RangeToInclusive<usize> {}
134 #[unstable(feature = "new_range_api", issue = "125687")]
135 impl Sealed for range::RangeFrom<usize> {}
136
137 impl Sealed for ops::IndexRange {}
138
139 #[unstable(feature = "sliceindex_wrappers", issue = "146179")]
140 impl Sealed for crate::index::Last {}
141 #[unstable(feature = "sliceindex_wrappers", issue = "146179")]
142 impl<T> Sealed for crate::index::Clamp<T> where T: Sealed {}
143}
144
145#[stable(feature = "slice_get_slice", since = "1.28.0")]
150#[rustc_diagnostic_item = "SliceIndex"]
151#[rustc_on_unimplemented(
152 on(T = "str", label = "string indices are ranges of `usize`",),
153 on(
154 all(any(T = "str", T = "&str", T = "alloc::string::String"), Self = "{integer}"),
155 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
156 for more information, see chapter 8 in The Book: \
157 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
158 ),
159 message = "the type `{T}` cannot be indexed by `{Self}`",
160 label = "slice indices are of type `usize` or ranges of `usize`"
161)]
162#[const_trait] #[rustc_const_unstable(feature = "const_index", issue = "143775")]
164pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
165 #[stable(feature = "slice_get_slice", since = "1.28.0")]
167 type Output: ?Sized;
168
169 #[unstable(feature = "slice_index_methods", issue = "none")]
172 fn get(self, slice: &T) -> Option<&Self::Output>;
173
174 #[unstable(feature = "slice_index_methods", issue = "none")]
177 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
178
179 #[unstable(feature = "slice_index_methods", issue = "none")]
187 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
188
189 #[unstable(feature = "slice_index_methods", issue = "none")]
197 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
198
199 #[unstable(feature = "slice_index_methods", issue = "none")]
202 #[track_caller]
203 fn index(self, slice: &T) -> &Self::Output;
204
205 #[unstable(feature = "slice_index_methods", issue = "none")]
208 #[track_caller]
209 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
210}
211
212#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
214#[rustc_const_unstable(feature = "const_index", issue = "143775")]
215unsafe impl<T> const SliceIndex<[T]> for usize {
216 type Output = T;
217
218 #[inline]
219 fn get(self, slice: &[T]) -> Option<&T> {
220 if self < slice.len() {
221 unsafe { Some(slice_get_unchecked(slice, self)) }
223 } else {
224 None
225 }
226 }
227
228 #[inline]
229 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
230 if self < slice.len() {
231 unsafe { Some(slice_get_unchecked(slice, self)) }
233 } else {
234 None
235 }
236 }
237
238 #[inline]
239 #[track_caller]
240 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
241 assert_unsafe_precondition!(
242 check_language_ub, "slice::get_unchecked requires that the index is within the slice",
244 (this: usize = self, len: usize = slice.len()) => this < len
245 );
246 unsafe {
251 crate::intrinsics::assume(self < slice.len());
254 slice_get_unchecked(slice, self)
255 }
256 }
257
258 #[inline]
259 #[track_caller]
260 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
261 assert_unsafe_precondition!(
262 check_library_ub,
263 "slice::get_unchecked_mut requires that the index is within the slice",
264 (this: usize = self, len: usize = slice.len()) => this < len
265 );
266 unsafe { slice_get_unchecked(slice, self) }
268 }
269
270 #[inline]
271 fn index(self, slice: &[T]) -> &T {
272 &(*slice)[self]
274 }
275
276 #[inline]
277 fn index_mut(self, slice: &mut [T]) -> &mut T {
278 &mut (*slice)[self]
280 }
281}
282
283#[rustc_const_unstable(feature = "const_index", issue = "143775")]
286unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
287 type Output = [T];
288
289 #[inline]
290 fn get(self, slice: &[T]) -> Option<&[T]> {
291 if self.end() <= slice.len() {
292 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
294 } else {
295 None
296 }
297 }
298
299 #[inline]
300 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
301 if self.end() <= slice.len() {
302 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
304 } else {
305 None
306 }
307 }
308
309 #[inline]
310 #[track_caller]
311 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
312 assert_unsafe_precondition!(
313 check_library_ub,
314 "slice::get_unchecked requires that the index is within the slice",
315 (end: usize = self.end(), len: usize = slice.len()) => end <= len
316 );
317 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
322 }
323
324 #[inline]
325 #[track_caller]
326 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
327 assert_unsafe_precondition!(
328 check_library_ub,
329 "slice::get_unchecked_mut requires that the index is within the slice",
330 (end: usize = self.end(), len: usize = slice.len()) => end <= len
331 );
332
333 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
335 }
336
337 #[inline]
338 fn index(self, slice: &[T]) -> &[T] {
339 if self.end() <= slice.len() {
340 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
342 } else {
343 slice_index_fail(self.start(), self.end(), slice.len())
344 }
345 }
346
347 #[inline]
348 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
349 if self.end() <= slice.len() {
350 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
352 } else {
353 slice_index_fail(self.start(), self.end(), slice.len())
354 }
355 }
356}
357
358#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
362#[rustc_const_unstable(feature = "const_index", issue = "143775")]
363unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
364 type Output = [T];
365
366 #[inline]
367 fn get(self, slice: &[T]) -> Option<&[T]> {
368 if let Some(new_len) = usize::checked_sub(self.end, self.start)
370 && self.end <= slice.len()
371 {
372 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
374 } else {
375 None
376 }
377 }
378
379 #[inline]
380 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
381 if let Some(new_len) = usize::checked_sub(self.end, self.start)
382 && self.end <= slice.len()
383 {
384 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
386 } else {
387 None
388 }
389 }
390
391 #[inline]
392 #[track_caller]
393 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
394 assert_unsafe_precondition!(
395 check_library_ub,
396 "slice::get_unchecked requires that the range is within the slice",
397 (
398 start: usize = self.start,
399 end: usize = self.end,
400 len: usize = slice.len()
401 ) => end >= start && end <= len
402 );
403
404 unsafe {
409 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
412 get_offset_len_noubcheck(slice, self.start, new_len)
413 }
414 }
415
416 #[inline]
417 #[track_caller]
418 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
419 assert_unsafe_precondition!(
420 check_library_ub,
421 "slice::get_unchecked_mut requires that the range is within the slice",
422 (
423 start: usize = self.start,
424 end: usize = self.end,
425 len: usize = slice.len()
426 ) => end >= start && end <= len
427 );
428 unsafe {
430 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
431 get_offset_len_mut_noubcheck(slice, self.start, new_len)
432 }
433 }
434
435 #[inline(always)]
436 fn index(self, slice: &[T]) -> &[T] {
437 if let Some(new_len) = usize::checked_sub(self.end, self.start)
439 && self.end <= slice.len()
440 {
441 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
443 } else {
444 slice_index_fail(self.start, self.end, slice.len())
445 }
446 }
447
448 #[inline]
449 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
450 if let Some(new_len) = usize::checked_sub(self.end, self.start)
452 && self.end <= slice.len()
453 {
454 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
456 } else {
457 slice_index_fail(self.start, self.end, slice.len())
458 }
459 }
460}
461
462#[unstable(feature = "new_range_api", issue = "125687")]
463#[rustc_const_unstable(feature = "const_index", issue = "143775")]
464unsafe impl<T> const SliceIndex<[T]> for range::Range<usize> {
465 type Output = [T];
466
467 #[inline]
468 fn get(self, slice: &[T]) -> Option<&[T]> {
469 ops::Range::from(self).get(slice)
470 }
471
472 #[inline]
473 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
474 ops::Range::from(self).get_mut(slice)
475 }
476
477 #[inline]
478 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
479 unsafe { ops::Range::from(self).get_unchecked(slice) }
481 }
482
483 #[inline]
484 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
485 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
487 }
488
489 #[inline(always)]
490 fn index(self, slice: &[T]) -> &[T] {
491 ops::Range::from(self).index(slice)
492 }
493
494 #[inline]
495 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
496 ops::Range::from(self).index_mut(slice)
497 }
498}
499
500#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
502#[rustc_const_unstable(feature = "const_index", issue = "143775")]
503unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
504 type Output = [T];
505
506 #[inline]
507 fn get(self, slice: &[T]) -> Option<&[T]> {
508 (0..self.end).get(slice)
509 }
510
511 #[inline]
512 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
513 (0..self.end).get_mut(slice)
514 }
515
516 #[inline]
517 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
518 unsafe { (0..self.end).get_unchecked(slice) }
520 }
521
522 #[inline]
523 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
524 unsafe { (0..self.end).get_unchecked_mut(slice) }
526 }
527
528 #[inline(always)]
529 fn index(self, slice: &[T]) -> &[T] {
530 (0..self.end).index(slice)
531 }
532
533 #[inline]
534 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
535 (0..self.end).index_mut(slice)
536 }
537}
538
539#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
541#[rustc_const_unstable(feature = "const_index", issue = "143775")]
542unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
543 type Output = [T];
544
545 #[inline]
546 fn get(self, slice: &[T]) -> Option<&[T]> {
547 (self.start..slice.len()).get(slice)
548 }
549
550 #[inline]
551 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
552 (self.start..slice.len()).get_mut(slice)
553 }
554
555 #[inline]
556 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
557 unsafe { (self.start..slice.len()).get_unchecked(slice) }
559 }
560
561 #[inline]
562 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
563 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
565 }
566
567 #[inline]
568 fn index(self, slice: &[T]) -> &[T] {
569 if self.start > slice.len() {
570 slice_index_fail(self.start, slice.len(), slice.len())
571 }
572 unsafe {
574 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
575 &*get_offset_len_noubcheck(slice, self.start, new_len)
576 }
577 }
578
579 #[inline]
580 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
581 if self.start > slice.len() {
582 slice_index_fail(self.start, slice.len(), slice.len())
583 }
584 unsafe {
586 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
587 &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)
588 }
589 }
590}
591
592#[unstable(feature = "new_range_api", issue = "125687")]
593#[rustc_const_unstable(feature = "const_index", issue = "143775")]
594unsafe impl<T> const SliceIndex<[T]> for range::RangeFrom<usize> {
595 type Output = [T];
596
597 #[inline]
598 fn get(self, slice: &[T]) -> Option<&[T]> {
599 ops::RangeFrom::from(self).get(slice)
600 }
601
602 #[inline]
603 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
604 ops::RangeFrom::from(self).get_mut(slice)
605 }
606
607 #[inline]
608 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
609 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
611 }
612
613 #[inline]
614 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
615 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
617 }
618
619 #[inline]
620 fn index(self, slice: &[T]) -> &[T] {
621 ops::RangeFrom::from(self).index(slice)
622 }
623
624 #[inline]
625 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
626 ops::RangeFrom::from(self).index_mut(slice)
627 }
628}
629
630#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
631#[rustc_const_unstable(feature = "const_index", issue = "143775")]
632unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
633 type Output = [T];
634
635 #[inline]
636 fn get(self, slice: &[T]) -> Option<&[T]> {
637 Some(slice)
638 }
639
640 #[inline]
641 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
642 Some(slice)
643 }
644
645 #[inline]
646 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
647 slice
648 }
649
650 #[inline]
651 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
652 slice
653 }
654
655 #[inline]
656 fn index(self, slice: &[T]) -> &[T] {
657 slice
658 }
659
660 #[inline]
661 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
662 slice
663 }
664}
665
666#[stable(feature = "inclusive_range", since = "1.26.0")]
671#[rustc_const_unstable(feature = "const_index", issue = "143775")]
672unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
673 type Output = [T];
674
675 #[inline]
676 fn get(self, slice: &[T]) -> Option<&[T]> {
677 if *self.end() == usize::MAX { None } else { self.into_slice_range().get(slice) }
678 }
679
680 #[inline]
681 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
682 if *self.end() == usize::MAX { None } else { self.into_slice_range().get_mut(slice) }
683 }
684
685 #[inline]
686 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
687 unsafe { self.into_slice_range().get_unchecked(slice) }
689 }
690
691 #[inline]
692 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
693 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
695 }
696
697 #[inline]
698 fn index(self, slice: &[T]) -> &[T] {
699 let Self { mut start, mut end, exhausted } = self;
700 let len = slice.len();
701 if end < len {
702 end = end + 1;
703 start = if exhausted { end } else { start };
704 if let Some(new_len) = usize::checked_sub(end, start) {
705 unsafe { return &*get_offset_len_noubcheck(slice, start, new_len) }
707 }
708 }
709 slice_index_fail(start, end, slice.len())
710 }
711
712 #[inline]
713 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
714 let Self { mut start, mut end, exhausted } = self;
715 let len = slice.len();
716 if end < len {
717 end = end + 1;
718 start = if exhausted { end } else { start };
719 if let Some(new_len) = usize::checked_sub(end, start) {
720 unsafe { return &mut *get_offset_len_mut_noubcheck(slice, start, new_len) }
722 }
723 }
724 slice_index_fail(start, end, slice.len())
725 }
726}
727
728#[unstable(feature = "new_range_api", issue = "125687")]
729#[rustc_const_unstable(feature = "const_index", issue = "143775")]
730unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
731 type Output = [T];
732
733 #[inline]
734 fn get(self, slice: &[T]) -> Option<&[T]> {
735 ops::RangeInclusive::from(self).get(slice)
736 }
737
738 #[inline]
739 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
740 ops::RangeInclusive::from(self).get_mut(slice)
741 }
742
743 #[inline]
744 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
745 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
747 }
748
749 #[inline]
750 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
751 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
753 }
754
755 #[inline]
756 fn index(self, slice: &[T]) -> &[T] {
757 ops::RangeInclusive::from(self).index(slice)
758 }
759
760 #[inline]
761 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
762 ops::RangeInclusive::from(self).index_mut(slice)
763 }
764}
765
766#[stable(feature = "inclusive_range", since = "1.26.0")]
768#[rustc_const_unstable(feature = "const_index", issue = "143775")]
769unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
770 type Output = [T];
771
772 #[inline]
773 fn get(self, slice: &[T]) -> Option<&[T]> {
774 (0..=self.end).get(slice)
775 }
776
777 #[inline]
778 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
779 (0..=self.end).get_mut(slice)
780 }
781
782 #[inline]
783 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
784 unsafe { (0..=self.end).get_unchecked(slice) }
786 }
787
788 #[inline]
789 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
790 unsafe { (0..=self.end).get_unchecked_mut(slice) }
792 }
793
794 #[inline]
795 fn index(self, slice: &[T]) -> &[T] {
796 (0..=self.end).index(slice)
797 }
798
799 #[inline]
800 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
801 (0..=self.end).index_mut(slice)
802 }
803}
804
805#[stable(feature = "inclusive_range", since = "1.26.0")]
807#[rustc_const_unstable(feature = "const_index", issue = "143775")]
808unsafe impl<T> const SliceIndex<[T]> for range::RangeToInclusive<usize> {
809 type Output = [T];
810
811 #[inline]
812 fn get(self, slice: &[T]) -> Option<&[T]> {
813 (0..=self.last).get(slice)
814 }
815
816 #[inline]
817 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
818 (0..=self.last).get_mut(slice)
819 }
820
821 #[inline]
822 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
823 unsafe { (0..=self.last).get_unchecked(slice) }
825 }
826
827 #[inline]
828 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
829 unsafe { (0..=self.last).get_unchecked_mut(slice) }
831 }
832
833 #[inline]
834 fn index(self, slice: &[T]) -> &[T] {
835 (0..=self.last).index(slice)
836 }
837
838 #[inline]
839 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
840 (0..=self.last).index_mut(slice)
841 }
842}
843
844#[track_caller]
906#[unstable(feature = "slice_range", issue = "76393")]
907#[must_use]
908#[rustc_const_unstable(feature = "const_range", issue = "none")]
909pub const fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
910where
911 R: [const] ops::RangeBounds<usize> + [const] Destruct,
912{
913 let len = bounds.end;
914
915 let end = match range.end_bound() {
916 ops::Bound::Included(&end) if end >= len => slice_index_fail(0, end, len),
917 ops::Bound::Included(&end) => end + 1,
919
920 ops::Bound::Excluded(&end) if end > len => slice_index_fail(0, end, len),
921 ops::Bound::Excluded(&end) => end,
922 ops::Bound::Unbounded => len,
923 };
924
925 let start = match range.start_bound() {
926 ops::Bound::Excluded(&start) if start >= end => slice_index_fail(start, end, len),
927 ops::Bound::Excluded(&start) => start + 1,
929
930 ops::Bound::Included(&start) if start > end => slice_index_fail(start, end, len),
931 ops::Bound::Included(&start) => start,
932
933 ops::Bound::Unbounded => 0,
934 };
935
936 ops::Range { start, end }
937}
938
939#[unstable(feature = "slice_range", issue = "76393")]
970#[must_use]
971pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
972where
973 R: ops::RangeBounds<usize>,
974{
975 let len = bounds.end;
976
977 let start = match range.start_bound() {
978 ops::Bound::Included(&start) => start,
979 ops::Bound::Excluded(start) => start.checked_add(1)?,
980 ops::Bound::Unbounded => 0,
981 };
982
983 let end = match range.end_bound() {
984 ops::Bound::Included(end) => end.checked_add(1)?,
985 ops::Bound::Excluded(&end) => end,
986 ops::Bound::Unbounded => len,
987 };
988
989 if start > end || end > len { None } else { Some(ops::Range { start, end }) }
990}
991
992pub(crate) const fn into_range_unchecked(
995 len: usize,
996 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
997) -> ops::Range<usize> {
998 use ops::Bound;
999 let start = match start {
1000 Bound::Included(i) => i,
1001 Bound::Excluded(i) => i + 1,
1002 Bound::Unbounded => 0,
1003 };
1004 let end = match end {
1005 Bound::Included(i) => i + 1,
1006 Bound::Excluded(i) => i,
1007 Bound::Unbounded => len,
1008 };
1009 start..end
1010}
1011
1012#[rustc_const_unstable(feature = "const_range", issue = "none")]
1015pub(crate) const fn into_range(
1016 len: usize,
1017 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1018) -> Option<ops::Range<usize>> {
1019 use ops::Bound;
1020 let start = match start {
1021 Bound::Included(start) => start,
1022 Bound::Excluded(start) => start.checked_add(1)?,
1023 Bound::Unbounded => 0,
1024 };
1025
1026 let end = match end {
1027 Bound::Included(end) => end.checked_add(1)?,
1028 Bound::Excluded(end) => end,
1029 Bound::Unbounded => len,
1030 };
1031
1032 Some(start..end)
1036}
1037
1038pub(crate) fn into_slice_range(
1041 len: usize,
1042 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1043) -> ops::Range<usize> {
1044 let end = match end {
1045 ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
1046 ops::Bound::Included(end) => end + 1,
1048
1049 ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
1050 ops::Bound::Excluded(end) => end,
1051
1052 ops::Bound::Unbounded => len,
1053 };
1054
1055 let start = match start {
1056 ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
1057 ops::Bound::Excluded(start) => start + 1,
1059
1060 ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
1061 ops::Bound::Included(start) => start,
1062
1063 ops::Bound::Unbounded => 0,
1064 };
1065
1066 start..end
1067}
1068
1069#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1070unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1071 type Output = [T];
1072
1073 #[inline]
1074 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1075 into_range(slice.len(), self)?.get(slice)
1076 }
1077
1078 #[inline]
1079 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1080 into_range(slice.len(), self)?.get_mut(slice)
1081 }
1082
1083 #[inline]
1084 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1085 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1087 }
1088
1089 #[inline]
1090 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1091 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1093 }
1094
1095 #[inline]
1096 fn index(self, slice: &[T]) -> &Self::Output {
1097 into_slice_range(slice.len(), self).index(slice)
1098 }
1099
1100 #[inline]
1101 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1102 into_slice_range(slice.len(), self).index_mut(slice)
1103 }
1104}