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")]
147 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
148
149 #[unstable(feature = "slice_index_methods", issue = "none")]
157 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
158
159 #[unstable(feature = "slice_index_methods", issue = "none")]
162 #[track_caller]
163 fn index(self, slice: &T) -> &Self::Output;
164
165 #[unstable(feature = "slice_index_methods", issue = "none")]
168 #[track_caller]
169 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
170}
171
172#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
174#[rustc_const_unstable(feature = "const_index", issue = "143775")]
175const unsafe impl<T> SliceIndex<[T]> for usize {
176 type Output = T;
177
178 #[inline]
179 fn get(self, slice: &[T]) -> Option<&T> {
180 if self < slice.len() {
181 unsafe { Some(slice_get_unchecked(slice, self)) }
183 } else {
184 None
185 }
186 }
187
188 #[inline]
189 #[rustc_no_writable]
190 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
191 if self < slice.len() {
192 unsafe { Some(slice_get_unchecked(slice, self)) }
194 } else {
195 None
196 }
197 }
198
199 #[inline]
200 #[track_caller]
201 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
202 assert_unsafe_precondition!(
203 check_language_ub, "slice::get_unchecked requires that the index is within the slice",
205 (this: usize = self, len: usize = slice.len()) => this < len
206 );
207 unsafe {
212 crate::intrinsics::assume(self < slice.len());
215 slice_get_unchecked(slice, self)
216 }
217 }
218
219 #[inline]
220 #[track_caller]
221 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
222 assert_unsafe_precondition!(
223 check_library_ub,
224 "slice::get_unchecked_mut requires that the index is within the slice",
225 (this: usize = self, len: usize = slice.len()) => this < len
226 );
227 unsafe { slice_get_unchecked(slice, self) }
229 }
230
231 #[inline]
232 fn index(self, slice: &[T]) -> &T {
233 &(*slice)[self]
235 }
236
237 #[inline]
238 #[rustc_no_writable]
239 fn index_mut(self, slice: &mut [T]) -> &mut T {
240 &mut (*slice)[self]
242 }
243}
244
245#[rustc_const_unstable(feature = "const_index", issue = "143775")]
248const unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
249 type Output = [T];
250
251 #[inline]
252 fn get(self, slice: &[T]) -> Option<&[T]> {
253 if self.end() <= slice.len() {
254 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
256 } else {
257 None
258 }
259 }
260
261 #[inline]
262 #[rustc_no_writable]
263 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
264 if self.end() <= slice.len() {
265 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
267 } else {
268 None
269 }
270 }
271
272 #[inline]
273 #[track_caller]
274 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
275 assert_unsafe_precondition!(
276 check_library_ub,
277 "slice::get_unchecked requires that the index is within the slice",
278 (end: usize = self.end(), len: usize = slice.len()) => end <= len
279 );
280 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
285 }
286
287 #[inline]
288 #[track_caller]
289 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
290 assert_unsafe_precondition!(
291 check_library_ub,
292 "slice::get_unchecked_mut requires that the index is within the slice",
293 (end: usize = self.end(), len: usize = slice.len()) => end <= len
294 );
295
296 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
298 }
299
300 #[inline]
301 fn index(self, slice: &[T]) -> &[T] {
302 if self.end() <= slice.len() {
303 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
305 } else {
306 slice_index_fail(self.start(), self.end(), slice.len())
307 }
308 }
309
310 #[inline]
311 #[rustc_no_writable]
312 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
313 if self.end() <= slice.len() {
314 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
316 } else {
317 slice_index_fail(self.start(), self.end(), slice.len())
318 }
319 }
320}
321
322#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
326#[rustc_const_unstable(feature = "const_index", issue = "143775")]
327const unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
328 type Output = [T];
329
330 #[inline]
331 fn get(self, slice: &[T]) -> Option<&[T]> {
332 if let Some(new_len) = usize::checked_sub(self.end, self.start)
334 && self.end <= slice.len()
335 {
336 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
338 } else {
339 None
340 }
341 }
342
343 #[inline]
344 #[rustc_no_writable]
345 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
346 if let Some(new_len) = usize::checked_sub(self.end, self.start)
347 && self.end <= slice.len()
348 {
349 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
351 } else {
352 None
353 }
354 }
355
356 #[inline]
357 #[track_caller]
358 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
359 assert_unsafe_precondition!(
360 check_library_ub,
361 "slice::get_unchecked requires that the range is within the slice",
362 (
363 start: usize = self.start,
364 end: usize = self.end,
365 len: usize = slice.len()
366 ) => end >= start && end <= len
367 );
368
369 unsafe {
374 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
377 get_offset_len_noubcheck(slice, self.start, new_len)
378 }
379 }
380
381 #[inline]
382 #[track_caller]
383 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
384 assert_unsafe_precondition!(
385 check_library_ub,
386 "slice::get_unchecked_mut requires that the range is within the slice",
387 (
388 start: usize = self.start,
389 end: usize = self.end,
390 len: usize = slice.len()
391 ) => end >= start && end <= len
392 );
393 unsafe {
395 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
396 get_offset_len_mut_noubcheck(slice, self.start, new_len)
397 }
398 }
399
400 #[inline(always)]
401 fn index(self, slice: &[T]) -> &[T] {
402 if let Some(new_len) = usize::checked_sub(self.end, self.start)
404 && self.end <= slice.len()
405 {
406 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
408 } else {
409 slice_index_fail(self.start, self.end, slice.len())
410 }
411 }
412
413 #[inline]
414 #[rustc_no_writable]
415 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
416 if let Some(new_len) = usize::checked_sub(self.end, self.start)
418 && self.end <= slice.len()
419 {
420 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
422 } else {
423 slice_index_fail(self.start, self.end, slice.len())
424 }
425 }
426}
427
428#[stable(feature = "new_range_api", since = "1.96.0")]
429#[rustc_const_unstable(feature = "const_index", issue = "143775")]
430const unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
431 type Output = [T];
432
433 #[inline]
434 fn get(self, slice: &[T]) -> Option<&[T]> {
435 ops::Range::from(self).get(slice)
436 }
437
438 #[inline]
439 #[rustc_no_writable]
440 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
441 ops::Range::from(self).get_mut(slice)
442 }
443
444 #[inline]
445 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
446 unsafe { ops::Range::from(self).get_unchecked(slice) }
448 }
449
450 #[inline]
451 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
452 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
454 }
455
456 #[inline(always)]
457 fn index(self, slice: &[T]) -> &[T] {
458 ops::Range::from(self).index(slice)
459 }
460
461 #[inline]
462 #[rustc_no_writable]
463 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
464 ops::Range::from(self).index_mut(slice)
465 }
466}
467
468#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
470#[rustc_const_unstable(feature = "const_index", issue = "143775")]
471const unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
472 type Output = [T];
473
474 #[inline]
475 fn get(self, slice: &[T]) -> Option<&[T]> {
476 (0..self.end).get(slice)
477 }
478
479 #[inline]
480 #[rustc_no_writable]
481 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
482 (0..self.end).get_mut(slice)
483 }
484
485 #[inline]
486 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
487 unsafe { (0..self.end).get_unchecked(slice) }
489 }
490
491 #[inline]
492 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
493 unsafe { (0..self.end).get_unchecked_mut(slice) }
495 }
496
497 #[inline(always)]
498 fn index(self, slice: &[T]) -> &[T] {
499 (0..self.end).index(slice)
500 }
501
502 #[inline]
503 #[rustc_no_writable]
504 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
505 (0..self.end).index_mut(slice)
506 }
507}
508
509#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
511#[rustc_const_unstable(feature = "const_index", issue = "143775")]
512const unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
513 type Output = [T];
514
515 #[inline]
516 fn get(self, slice: &[T]) -> Option<&[T]> {
517 (self.start..slice.len()).get(slice)
518 }
519
520 #[inline]
521 #[rustc_no_writable]
522 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
523 (self.start..slice.len()).get_mut(slice)
524 }
525
526 #[inline]
527 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
528 unsafe { (self.start..slice.len()).get_unchecked(slice) }
530 }
531
532 #[inline]
533 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
534 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
536 }
537
538 #[inline]
539 fn index(self, slice: &[T]) -> &[T] {
540 if self.start > slice.len() {
541 slice_index_fail(self.start, slice.len(), slice.len())
542 }
543 unsafe {
545 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
546 &*get_offset_len_noubcheck(slice, self.start, new_len)
547 }
548 }
549
550 #[inline]
551 #[rustc_no_writable]
552 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
553 if self.start > slice.len() {
554 slice_index_fail(self.start, slice.len(), slice.len())
555 }
556 unsafe {
558 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
559 &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)
560 }
561 }
562}
563
564#[stable(feature = "new_range_from_api", since = "1.96.0")]
565#[rustc_const_unstable(feature = "const_index", issue = "143775")]
566const unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
567 type Output = [T];
568
569 #[inline]
570 fn get(self, slice: &[T]) -> Option<&[T]> {
571 ops::RangeFrom::from(self).get(slice)
572 }
573
574 #[inline]
575 #[rustc_no_writable]
576 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
577 ops::RangeFrom::from(self).get_mut(slice)
578 }
579
580 #[inline]
581 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
582 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
584 }
585
586 #[inline]
587 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
588 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
590 }
591
592 #[inline]
593 fn index(self, slice: &[T]) -> &[T] {
594 ops::RangeFrom::from(self).index(slice)
595 }
596
597 #[inline]
598 #[rustc_no_writable]
599 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
600 ops::RangeFrom::from(self).index_mut(slice)
601 }
602}
603
604#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
605#[rustc_const_unstable(feature = "const_index", issue = "143775")]
606const unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
607 type Output = [T];
608
609 #[inline]
610 fn get(self, slice: &[T]) -> Option<&[T]> {
611 Some(slice)
612 }
613
614 #[inline]
615 #[rustc_no_writable]
616 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
617 Some(slice)
618 }
619
620 #[inline]
621 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
622 slice
623 }
624
625 #[inline]
626 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
627 slice
628 }
629
630 #[inline]
631 fn index(self, slice: &[T]) -> &[T] {
632 slice
633 }
634
635 #[inline]
636 #[rustc_no_writable]
637 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
638 slice
639 }
640}
641
642#[stable(feature = "inclusive_range", since = "1.26.0")]
646#[rustc_const_unstable(feature = "const_index", issue = "143775")]
647const unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
648 type Output = [T];
649
650 #[inline]
651 fn get(self, slice: &[T]) -> Option<&[T]> {
652 if *self.end() >= slice.len() { None } else { self.into_slice_range().get(slice) }
653 }
654
655 #[inline]
656 #[rustc_no_writable]
657 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
658 if *self.end() >= slice.len() { None } else { self.into_slice_range().get_mut(slice) }
659 }
660
661 #[inline]
662 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
663 unsafe { self.into_slice_range().get_unchecked(slice) }
665 }
666
667 #[inline]
668 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
669 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
671 }
672
673 #[inline]
674 fn index(self, slice: &[T]) -> &[T] {
675 let Self { mut start, mut end, exhausted } = self;
676 let len = slice.len();
677 if end < len {
678 end = end + 1;
679 start = if exhausted { end } else { start };
680 if let Some(new_len) = usize::checked_sub(end, start) {
681 unsafe { return &*get_offset_len_noubcheck(slice, start, new_len) }
683 }
684 }
685 slice_index_fail(start, end, slice.len())
686 }
687
688 #[inline]
689 #[rustc_no_writable]
690 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
691 let Self { mut start, mut end, exhausted } = self;
692 let len = slice.len();
693 if end < len {
694 end = end + 1;
695 start = if exhausted { end } else { start };
696 if let Some(new_len) = usize::checked_sub(end, start) {
697 unsafe { return &mut *get_offset_len_mut_noubcheck(slice, start, new_len) }
699 }
700 }
701 slice_index_fail(start, end, slice.len())
702 }
703}
704
705#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
706#[rustc_const_unstable(feature = "const_index", issue = "143775")]
707const unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
708 type Output = [T];
709
710 #[inline]
711 fn get(self, slice: &[T]) -> Option<&[T]> {
712 ops::RangeInclusive::from(self).get(slice)
713 }
714
715 #[inline]
716 #[rustc_no_writable]
717 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
718 ops::RangeInclusive::from(self).get_mut(slice)
719 }
720
721 #[inline]
722 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
723 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
725 }
726
727 #[inline]
728 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
729 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
731 }
732
733 #[inline]
734 fn index(self, slice: &[T]) -> &[T] {
735 ops::RangeInclusive::from(self).index(slice)
736 }
737
738 #[inline]
739 #[rustc_no_writable]
740 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
741 ops::RangeInclusive::from(self).index_mut(slice)
742 }
743}
744
745#[stable(feature = "inclusive_range", since = "1.26.0")]
747#[rustc_const_unstable(feature = "const_index", issue = "143775")]
748const unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
749 type Output = [T];
750
751 #[inline]
752 fn get(self, slice: &[T]) -> Option<&[T]> {
753 (0..=self.end).get(slice)
754 }
755
756 #[inline]
757 #[rustc_no_writable]
758 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
759 (0..=self.end).get_mut(slice)
760 }
761
762 #[inline]
763 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
764 unsafe { (0..=self.end).get_unchecked(slice) }
766 }
767
768 #[inline]
769 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
770 unsafe { (0..=self.end).get_unchecked_mut(slice) }
772 }
773
774 #[inline]
775 fn index(self, slice: &[T]) -> &[T] {
776 (0..=self.end).index(slice)
777 }
778
779 #[inline]
780 #[rustc_no_writable]
781 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
782 (0..=self.end).index_mut(slice)
783 }
784}
785
786#[stable(feature = "new_range_to_inclusive_api", since = "1.96.0")]
788#[rustc_const_unstable(feature = "const_index", issue = "143775")]
789const unsafe impl<T> SliceIndex<[T]> for range::RangeToInclusive<usize> {
790 type Output = [T];
791
792 #[inline]
793 fn get(self, slice: &[T]) -> Option<&[T]> {
794 (0..=self.last).get(slice)
795 }
796
797 #[inline]
798 #[rustc_no_writable]
799 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
800 (0..=self.last).get_mut(slice)
801 }
802
803 #[inline]
804 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
805 unsafe { (0..=self.last).get_unchecked(slice) }
807 }
808
809 #[inline]
810 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
811 unsafe { (0..=self.last).get_unchecked_mut(slice) }
813 }
814
815 #[inline]
816 fn index(self, slice: &[T]) -> &[T] {
817 (0..=self.last).index(slice)
818 }
819
820 #[inline]
821 #[rustc_no_writable]
822 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
823 (0..=self.last).index_mut(slice)
824 }
825}
826
827#[track_caller]
889#[unstable(feature = "slice_range", issue = "76393")]
890#[must_use]
891#[rustc_const_unstable(feature = "const_range", issue = "none")]
892pub const fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
893where
894 R: [const] ops::RangeBounds<usize> + [const] Destruct,
895{
896 let len = bounds.end;
897 into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
898}
899
900#[unstable(feature = "slice_range", issue = "76393")]
931#[must_use]
932pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
933where
934 R: ops::RangeBounds<usize>,
935{
936 let len = bounds.end;
937 try_into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
938}
939
940pub(crate) const fn into_range_unchecked(
943 len: usize,
944 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
945) -> ops::Range<usize> {
946 use ops::Bound;
947 let start = match start {
948 Bound::Included(i) => i,
949 Bound::Excluded(i) => i + 1,
950 Bound::Unbounded => 0,
951 };
952 let end = match end {
953 Bound::Included(i) => i + 1,
954 Bound::Excluded(i) => i,
955 Bound::Unbounded => len,
956 };
957 start..end
958}
959
960#[rustc_const_unstable(feature = "const_range", issue = "none")]
963#[inline]
964pub(crate) const fn try_into_slice_range(
965 len: usize,
966 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
967) -> Option<ops::Range<usize>> {
968 let end = match end {
969 ops::Bound::Included(end) if end >= len => return None,
970 ops::Bound::Included(end) => end + 1,
972
973 ops::Bound::Excluded(end) if end > len => return None,
974 ops::Bound::Excluded(end) => end,
975
976 ops::Bound::Unbounded => len,
977 };
978
979 let start = match start {
980 ops::Bound::Excluded(start) if start >= end => return None,
981 ops::Bound::Excluded(start) => start + 1,
983
984 ops::Bound::Included(start) if start > end => return None,
985 ops::Bound::Included(start) => start,
986
987 ops::Bound::Unbounded => 0,
988 };
989
990 Some(start..end)
991}
992
993#[inline]
996pub(crate) const fn into_slice_range(
997 len: usize,
998 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
999) -> ops::Range<usize> {
1000 let end = match end {
1001 ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
1002 ops::Bound::Included(end) => end + 1,
1004
1005 ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
1006 ops::Bound::Excluded(end) => end,
1007
1008 ops::Bound::Unbounded => len,
1009 };
1010
1011 let start = match start {
1012 ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
1013 ops::Bound::Excluded(start) => start + 1,
1015
1016 ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
1017 ops::Bound::Included(start) => start,
1018
1019 ops::Bound::Unbounded => 0,
1020 };
1021
1022 start..end
1023}
1024
1025#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1026unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1027 type Output = [T];
1028
1029 #[inline]
1030 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1031 try_into_slice_range(slice.len(), self)?.get(slice)
1032 }
1033
1034 #[inline]
1035 #[rustc_no_writable]
1036 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1037 try_into_slice_range(slice.len(), self)?.get_mut(slice)
1038 }
1039
1040 #[inline]
1041 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1042 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1044 }
1045
1046 #[inline]
1047 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1048 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1050 }
1051
1052 #[inline]
1053 fn index(self, slice: &[T]) -> &Self::Output {
1054 into_slice_range(slice.len(), self).index(slice)
1055 }
1056
1057 #[inline]
1058 #[rustc_no_writable]
1059 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1060 into_slice_range(slice.len(), self).index_mut(slice)
1061 }
1062}