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")]
11const impl<T, I> 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")]
25const impl<T, I> ops::IndexMut<I> for [T]
26where
27 I: [const] SliceIndex<[T]>,
28{
29 #[inline(always)]
30 #[rustc_no_writable]
31 fn index_mut(&mut self, index: I) -> &mut I::Output {
32 index.index_mut(self)
33 }
34}
35
36#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
37#[cfg_attr(panic = "immediate-abort", inline)]
38#[track_caller]
39const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
40 if start > len {
41 const_panic!(
42 "slice start index is out of range for slice",
43 "range start index {start} out of range for slice of length {len}",
44 start: usize,
45 len: usize,
46 )
47 }
48
49 if end > len {
50 const_panic!(
51 "slice end index is out of range for slice",
52 "range end index {end} out of range for slice of length {len}",
53 end: usize,
54 len: usize,
55 )
56 }
57
58 if start > end {
59 const_panic!(
60 "slice index start is larger than end",
61 "slice index starts at {start} but ends at {end}",
62 start: usize,
63 end: usize,
64 )
65 }
66
67 const_panic!(
70 "slice end index is out of range for slice",
71 "range end index {end} out of range for slice of length {len}",
72 end: usize,
73 len: usize,
74 )
75}
76
77#[inline(always)]
83const unsafe fn get_offset_len_noubcheck<T>(
84 ptr: *const [T],
85 offset: usize,
86 len: usize,
87) -> *const [T] {
88 let ptr = ptr as *const T;
89 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
91 crate::intrinsics::aggregate_raw_ptr(ptr, len)
92}
93
94#[inline(always)]
95const unsafe fn get_offset_len_mut_noubcheck<T>(
96 ptr: *mut [T],
97 offset: usize,
98 len: usize,
99) -> *mut [T] {
100 let ptr = ptr as *mut T;
101 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
103 crate::intrinsics::aggregate_raw_ptr(ptr, len)
104}
105
106#[stable(feature = "slice_get_slice", since = "1.28.0")]
111#[rustc_diagnostic_item = "SliceIndex"]
112#[rustc_on_unimplemented(
113 on(T = "str", label = "string indices are ranges of `usize`",),
114 on(
115 all(any(T = "str", T = "&str", T = "alloc::string::String"), Self = "{integer}"),
116 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
117 for more information, see chapter 8 in The Book: \
118 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
119 ),
120 message = "the type `{T}` cannot be indexed by `{Self}`",
121 label = "slice indices are of type `usize` or ranges of `usize`"
122)]
123#[rustc_const_unstable(feature = "const_index", issue = "143775")]
124pub impl(crate) const unsafe trait SliceIndex<T: ?Sized> {
125 #[stable(feature = "slice_get_slice", since = "1.28.0")]
127 type Output: ?Sized;
128
129 #[unstable(feature = "slice_index_methods", issue = "none")]
132 fn get(self, slice: &T) -> Option<&Self::Output>;
133
134 #[unstable(feature = "slice_index_methods", issue = "none")]
137 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
138
139 #[unstable(feature = "slice_index_methods", issue = "none")]
149 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
150
151 #[unstable(feature = "slice_index_methods", issue = "none")]
161 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
162
163 #[unstable(feature = "slice_index_methods", issue = "none")]
166 #[track_caller]
167 fn index(self, slice: &T) -> &Self::Output;
168
169 #[unstable(feature = "slice_index_methods", issue = "none")]
172 #[track_caller]
173 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
174}
175
176#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
178#[rustc_const_unstable(feature = "const_index", issue = "143775")]
179const unsafe impl<T> SliceIndex<[T]> for usize {
180 type Output = T;
181
182 #[inline]
183 fn get(self, slice: &[T]) -> Option<&T> {
184 if self < slice.len() {
185 unsafe { Some(slice_get_unchecked(slice, self)) }
187 } else {
188 None
189 }
190 }
191
192 #[inline]
193 #[rustc_no_writable]
194 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
195 if self < slice.len() {
196 unsafe { Some(slice_get_unchecked(slice, self)) }
198 } else {
199 None
200 }
201 }
202
203 #[inline]
204 #[track_caller]
205 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
206 assert_unsafe_precondition!(
207 check_language_ub, "slice::get_unchecked requires that the index is within the slice",
209 (this: usize = self, len: usize = slice.len()) => this < len
210 );
211 unsafe {
216 crate::intrinsics::assume(self < slice.len());
219 slice_get_unchecked(slice, self)
220 }
221 }
222
223 #[inline]
224 #[track_caller]
225 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
226 assert_unsafe_precondition!(
227 check_library_ub,
228 "slice::get_unchecked_mut requires that the index is within the slice",
229 (this: usize = self, len: usize = slice.len()) => this < len
230 );
231 unsafe { slice_get_unchecked(slice, self) }
233 }
234
235 #[inline]
236 fn index(self, slice: &[T]) -> &T {
237 &(*slice)[self]
239 }
240
241 #[inline]
242 #[rustc_no_writable]
243 fn index_mut(self, slice: &mut [T]) -> &mut T {
244 &mut (*slice)[self]
246 }
247}
248
249#[rustc_const_unstable(feature = "const_index", issue = "143775")]
252const unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
253 type Output = [T];
254
255 #[inline]
256 fn get(self, slice: &[T]) -> Option<&[T]> {
257 if self.end() <= slice.len() {
258 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
260 } else {
261 None
262 }
263 }
264
265 #[inline]
266 #[rustc_no_writable]
267 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
268 if self.end() <= slice.len() {
269 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
271 } else {
272 None
273 }
274 }
275
276 #[inline]
277 #[track_caller]
278 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
279 assert_unsafe_precondition!(
280 check_library_ub,
281 "slice::get_unchecked requires that the index is within the slice",
282 (end: usize = self.end(), len: usize = slice.len()) => end <= len
283 );
284 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
289 }
290
291 #[inline]
292 #[track_caller]
293 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
294 assert_unsafe_precondition!(
295 check_library_ub,
296 "slice::get_unchecked_mut requires that the index is within the slice",
297 (end: usize = self.end(), len: usize = slice.len()) => end <= len
298 );
299
300 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
302 }
303
304 #[inline]
305 fn index(self, slice: &[T]) -> &[T] {
306 if self.end() <= slice.len() {
307 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
309 } else {
310 slice_index_fail(self.start(), self.end(), slice.len())
311 }
312 }
313
314 #[inline]
315 #[rustc_no_writable]
316 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
317 if self.end() <= slice.len() {
318 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
320 } else {
321 slice_index_fail(self.start(), self.end(), slice.len())
322 }
323 }
324}
325
326#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
330#[rustc_const_unstable(feature = "const_index", issue = "143775")]
331const unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
332 type Output = [T];
333
334 #[inline]
335 fn get(self, slice: &[T]) -> Option<&[T]> {
336 if let Some(new_len) = usize::checked_sub(self.end, self.start)
338 && self.end <= slice.len()
339 {
340 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
342 } else {
343 None
344 }
345 }
346
347 #[inline]
348 #[rustc_no_writable]
349 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
350 if let Some(new_len) = usize::checked_sub(self.end, self.start)
351 && self.end <= slice.len()
352 {
353 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
355 } else {
356 None
357 }
358 }
359
360 #[inline]
361 #[track_caller]
362 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
363 assert_unsafe_precondition!(
364 check_library_ub,
365 "slice::get_unchecked requires that the range is within the slice",
366 (
367 start: usize = self.start,
368 end: usize = self.end,
369 len: usize = slice.len()
370 ) => end >= start && end <= len
371 );
372
373 unsafe {
378 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
381 get_offset_len_noubcheck(slice, self.start, new_len)
382 }
383 }
384
385 #[inline]
386 #[track_caller]
387 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
388 assert_unsafe_precondition!(
389 check_library_ub,
390 "slice::get_unchecked_mut requires that the range is within the slice",
391 (
392 start: usize = self.start,
393 end: usize = self.end,
394 len: usize = slice.len()
395 ) => end >= start && end <= len
396 );
397 unsafe {
399 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
400 get_offset_len_mut_noubcheck(slice, self.start, new_len)
401 }
402 }
403
404 #[inline(always)]
405 fn index(self, slice: &[T]) -> &[T] {
406 if let Some(new_len) = usize::checked_sub(self.end, self.start)
408 && self.end <= slice.len()
409 {
410 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
412 } else {
413 slice_index_fail(self.start, self.end, slice.len())
414 }
415 }
416
417 #[inline]
418 #[rustc_no_writable]
419 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
420 if let Some(new_len) = usize::checked_sub(self.end, self.start)
422 && self.end <= slice.len()
423 {
424 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
426 } else {
427 slice_index_fail(self.start, self.end, slice.len())
428 }
429 }
430}
431
432#[stable(feature = "new_range_api", since = "1.96.0")]
433#[rustc_const_unstable(feature = "const_index", issue = "143775")]
434const unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
435 type Output = [T];
436
437 #[inline]
438 fn get(self, slice: &[T]) -> Option<&[T]> {
439 ops::Range::from(self).get(slice)
440 }
441
442 #[inline]
443 #[rustc_no_writable]
444 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
445 ops::Range::from(self).get_mut(slice)
446 }
447
448 #[inline]
449 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
450 unsafe { ops::Range::from(self).get_unchecked(slice) }
452 }
453
454 #[inline]
455 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
456 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
458 }
459
460 #[inline(always)]
461 fn index(self, slice: &[T]) -> &[T] {
462 ops::Range::from(self).index(slice)
463 }
464
465 #[inline]
466 #[rustc_no_writable]
467 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
468 ops::Range::from(self).index_mut(slice)
469 }
470}
471
472#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
474#[rustc_const_unstable(feature = "const_index", issue = "143775")]
475const unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
476 type Output = [T];
477
478 #[inline]
479 fn get(self, slice: &[T]) -> Option<&[T]> {
480 (0..self.end).get(slice)
481 }
482
483 #[inline]
484 #[rustc_no_writable]
485 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
486 (0..self.end).get_mut(slice)
487 }
488
489 #[inline]
490 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
491 unsafe { (0..self.end).get_unchecked(slice) }
493 }
494
495 #[inline]
496 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
497 unsafe { (0..self.end).get_unchecked_mut(slice) }
499 }
500
501 #[inline(always)]
502 fn index(self, slice: &[T]) -> &[T] {
503 (0..self.end).index(slice)
504 }
505
506 #[inline]
507 #[rustc_no_writable]
508 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
509 (0..self.end).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")]
516const unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
517 type Output = [T];
518
519 #[inline]
520 fn get(self, slice: &[T]) -> Option<&[T]> {
521 (self.start..slice.len()).get(slice)
522 }
523
524 #[inline]
525 #[rustc_no_writable]
526 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
527 (self.start..slice.len()).get_mut(slice)
528 }
529
530 #[inline]
531 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
532 unsafe { (self.start..slice.len()).get_unchecked(slice) }
534 }
535
536 #[inline]
537 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
538 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
540 }
541
542 #[inline]
543 fn index(self, slice: &[T]) -> &[T] {
544 if self.start > slice.len() {
545 slice_index_fail(self.start, slice.len(), slice.len())
546 }
547 unsafe {
549 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
550 &*get_offset_len_noubcheck(slice, self.start, new_len)
551 }
552 }
553
554 #[inline]
555 #[rustc_no_writable]
556 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
557 if self.start > slice.len() {
558 slice_index_fail(self.start, slice.len(), slice.len())
559 }
560 unsafe {
562 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
563 &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)
564 }
565 }
566}
567
568#[stable(feature = "new_range_from_api", since = "1.96.0")]
569#[rustc_const_unstable(feature = "const_index", issue = "143775")]
570const unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
571 type Output = [T];
572
573 #[inline]
574 fn get(self, slice: &[T]) -> Option<&[T]> {
575 ops::RangeFrom::from(self).get(slice)
576 }
577
578 #[inline]
579 #[rustc_no_writable]
580 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
581 ops::RangeFrom::from(self).get_mut(slice)
582 }
583
584 #[inline]
585 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
586 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
588 }
589
590 #[inline]
591 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
592 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
594 }
595
596 #[inline]
597 fn index(self, slice: &[T]) -> &[T] {
598 ops::RangeFrom::from(self).index(slice)
599 }
600
601 #[inline]
602 #[rustc_no_writable]
603 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
604 ops::RangeFrom::from(self).index_mut(slice)
605 }
606}
607
608#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
609#[rustc_const_unstable(feature = "const_index", issue = "143775")]
610const unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
611 type Output = [T];
612
613 #[inline]
614 fn get(self, slice: &[T]) -> Option<&[T]> {
615 Some(slice)
616 }
617
618 #[inline]
619 #[rustc_no_writable]
620 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
621 Some(slice)
622 }
623
624 #[inline]
625 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
626 slice
627 }
628
629 #[inline]
630 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
631 slice
632 }
633
634 #[inline]
635 fn index(self, slice: &[T]) -> &[T] {
636 slice
637 }
638
639 #[inline]
640 #[rustc_no_writable]
641 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
642 slice
643 }
644}
645
646#[stable(feature = "inclusive_range", since = "1.26.0")]
650#[rustc_const_unstable(feature = "const_index", issue = "143775")]
651const unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
652 type Output = [T];
653
654 #[inline]
655 fn get(self, slice: &[T]) -> Option<&[T]> {
656 if *self.end() >= slice.len() { None } else { self.into_slice_range().get(slice) }
657 }
658
659 #[inline]
660 #[rustc_no_writable]
661 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
662 if *self.end() >= slice.len() { None } else { self.into_slice_range().get_mut(slice) }
663 }
664
665 #[inline]
666 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
667 unsafe { self.into_slice_range().get_unchecked(slice) }
669 }
670
671 #[inline]
672 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
673 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
675 }
676
677 #[inline]
678 fn index(self, slice: &[T]) -> &[T] {
679 let Self { mut start, mut end, exhausted } = self;
680 let len = slice.len();
681 if end < len {
682 end = end + 1;
683 start = if exhausted { end } else { start };
684 if let Some(new_len) = usize::checked_sub(end, start) {
685 unsafe { return &*get_offset_len_noubcheck(slice, start, new_len) }
687 }
688 }
689 slice_index_fail(start, end, slice.len())
690 }
691
692 #[inline]
693 #[rustc_no_writable]
694 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
695 let Self { mut start, mut end, exhausted } = self;
696 let len = slice.len();
697 if end < len {
698 end = end + 1;
699 start = if exhausted { end } else { start };
700 if let Some(new_len) = usize::checked_sub(end, start) {
701 unsafe { return &mut *get_offset_len_mut_noubcheck(slice, start, new_len) }
703 }
704 }
705 slice_index_fail(start, end, slice.len())
706 }
707}
708
709#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
710#[rustc_const_unstable(feature = "const_index", issue = "143775")]
711const unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
712 type Output = [T];
713
714 #[inline]
715 fn get(self, slice: &[T]) -> Option<&[T]> {
716 ops::RangeInclusive::from(self).get(slice)
717 }
718
719 #[inline]
720 #[rustc_no_writable]
721 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
722 ops::RangeInclusive::from(self).get_mut(slice)
723 }
724
725 #[inline]
726 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
727 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
729 }
730
731 #[inline]
732 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
733 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
735 }
736
737 #[inline]
738 fn index(self, slice: &[T]) -> &[T] {
739 ops::RangeInclusive::from(self).index(slice)
740 }
741
742 #[inline]
743 #[rustc_no_writable]
744 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
745 ops::RangeInclusive::from(self).index_mut(slice)
746 }
747}
748
749#[stable(feature = "inclusive_range", since = "1.26.0")]
751#[rustc_const_unstable(feature = "const_index", issue = "143775")]
752const unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
753 type Output = [T];
754
755 #[inline]
756 fn get(self, slice: &[T]) -> Option<&[T]> {
757 (0..=self.end).get(slice)
758 }
759
760 #[inline]
761 #[rustc_no_writable]
762 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
763 (0..=self.end).get_mut(slice)
764 }
765
766 #[inline]
767 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
768 unsafe { (0..=self.end).get_unchecked(slice) }
770 }
771
772 #[inline]
773 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
774 unsafe { (0..=self.end).get_unchecked_mut(slice) }
776 }
777
778 #[inline]
779 fn index(self, slice: &[T]) -> &[T] {
780 (0..=self.end).index(slice)
781 }
782
783 #[inline]
784 #[rustc_no_writable]
785 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
786 (0..=self.end).index_mut(slice)
787 }
788}
789
790#[stable(feature = "new_range_to_inclusive_api", since = "1.96.0")]
792#[rustc_const_unstable(feature = "const_index", issue = "143775")]
793const unsafe impl<T> SliceIndex<[T]> for range::RangeToInclusive<usize> {
794 type Output = [T];
795
796 #[inline]
797 fn get(self, slice: &[T]) -> Option<&[T]> {
798 (0..=self.last).get(slice)
799 }
800
801 #[inline]
802 #[rustc_no_writable]
803 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
804 (0..=self.last).get_mut(slice)
805 }
806
807 #[inline]
808 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
809 unsafe { (0..=self.last).get_unchecked(slice) }
811 }
812
813 #[inline]
814 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
815 unsafe { (0..=self.last).get_unchecked_mut(slice) }
817 }
818
819 #[inline]
820 fn index(self, slice: &[T]) -> &[T] {
821 (0..=self.last).index(slice)
822 }
823
824 #[inline]
825 #[rustc_no_writable]
826 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
827 (0..=self.last).index_mut(slice)
828 }
829}
830
831#[track_caller]
893#[unstable(feature = "slice_range", issue = "76393")]
894#[must_use]
895#[rustc_const_unstable(feature = "const_range", issue = "none")]
896pub const fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
897where
898 R: [const] ops::RangeBounds<usize> + [const] Destruct,
899{
900 let len = bounds.end;
901 into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
902}
903
904#[unstable(feature = "slice_range", issue = "76393")]
935#[must_use]
936pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
937where
938 R: ops::RangeBounds<usize>,
939{
940 let len = bounds.end;
941 try_into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
942}
943
944pub(crate) const fn into_range_unchecked(
947 len: usize,
948 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
949) -> ops::Range<usize> {
950 use ops::Bound;
951 let start = match start {
952 Bound::Included(i) => i,
953 Bound::Excluded(i) => i + 1,
954 Bound::Unbounded => 0,
955 };
956 let end = match end {
957 Bound::Included(i) => i + 1,
958 Bound::Excluded(i) => i,
959 Bound::Unbounded => len,
960 };
961 start..end
962}
963
964#[rustc_const_unstable(feature = "const_range", issue = "none")]
967#[inline]
968pub(crate) const fn try_into_slice_range(
969 len: usize,
970 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
971) -> Option<ops::Range<usize>> {
972 let end = match end {
973 ops::Bound::Included(end) if end >= len => return None,
974 ops::Bound::Included(end) => end + 1,
976
977 ops::Bound::Excluded(end) if end > len => return None,
978 ops::Bound::Excluded(end) => end,
979
980 ops::Bound::Unbounded => len,
981 };
982
983 let start = match start {
984 ops::Bound::Excluded(start) if start >= end => return None,
985 ops::Bound::Excluded(start) => start + 1,
987
988 ops::Bound::Included(start) if start > end => return None,
989 ops::Bound::Included(start) => start,
990
991 ops::Bound::Unbounded => 0,
992 };
993
994 Some(start..end)
995}
996
997#[inline]
1000pub(crate) const fn into_slice_range(
1001 len: usize,
1002 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1003) -> ops::Range<usize> {
1004 let end = match end {
1005 ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
1006 ops::Bound::Included(end) => end + 1,
1008
1009 ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
1010 ops::Bound::Excluded(end) => end,
1011
1012 ops::Bound::Unbounded => len,
1013 };
1014
1015 let start = match start {
1016 ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
1017 ops::Bound::Excluded(start) => start + 1,
1019
1020 ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
1021 ops::Bound::Included(start) => start,
1022
1023 ops::Bound::Unbounded => 0,
1024 };
1025
1026 start..end
1027}
1028
1029#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1030unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1031 type Output = [T];
1032
1033 #[inline]
1034 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1035 try_into_slice_range(slice.len(), self)?.get(slice)
1036 }
1037
1038 #[inline]
1039 #[rustc_no_writable]
1040 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1041 try_into_slice_range(slice.len(), self)?.get_mut(slice)
1042 }
1043
1044 #[inline]
1045 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1046 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1048 }
1049
1050 #[inline]
1051 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1052 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1054 }
1055
1056 #[inline]
1057 fn index(self, slice: &[T]) -> &Self::Output {
1058 into_slice_range(slice.len(), self).index(slice)
1059 }
1060
1061 #[inline]
1062 #[rustc_no_writable]
1063 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1064 into_slice_range(slice.len(), self).index_mut(slice)
1065 }
1066}