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 #[ferrocene::prevalidated]
19 fn index(&self, index: I) -> &I::Output {
20 index.index(self)
21 }
22}
23
24#[stable(feature = "rust1", since = "1.0.0")]
25#[rustc_const_unstable(feature = "const_index", issue = "143775")]
26const impl<T, I> ops::IndexMut<I> for [T]
27where
28 I: [const] SliceIndex<[T]>,
29{
30 #[ferrocene::prevalidated]
31 #[inline(always)]
32 #[rustc_no_writable]
33 fn index_mut(&mut self, index: I) -> &mut I::Output {
34 index.index_mut(self)
35 }
36}
37
38#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
39#[cfg_attr(panic = "immediate-abort", inline)]
40#[track_caller]
41#[ferrocene::prevalidated]
42const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
43 if start > len {
44 const_panic!(
45 "slice start index is out of range for slice",
46 "range start index {start} out of range for slice of length {len}",
47 start: usize,
48 len: usize,
49 )
50 }
51
52 if end > len {
53 const_panic!(
54 "slice end index is out of range for slice",
55 "range end index {end} out of range for slice of length {len}",
56 end: usize,
57 len: usize,
58 )
59 }
60
61 if start > end {
62 const_panic!(
63 "slice index start is larger than end",
64 "slice index starts at {start} but ends at {end}",
65 start: usize,
66 end: usize,
67 )
68 }
69
70 const_panic!(
73 "slice end index is out of range for slice",
74 "range end index {end} out of range for slice of length {len}",
75 end: usize,
76 len: usize,
77 )
78}
79
80#[inline(always)]
86#[ferrocene::prevalidated]
87const unsafe fn get_offset_len_noubcheck<T>(
88 ptr: *const [T],
89 offset: usize,
90 len: usize,
91) -> *const [T] {
92 let ptr = ptr as *const T;
93 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
95 crate::intrinsics::aggregate_raw_ptr(ptr, len)
96}
97
98#[inline(always)]
99#[ferrocene::prevalidated]
100const unsafe fn get_offset_len_mut_noubcheck<T>(
101 ptr: *mut [T],
102 offset: usize,
103 len: usize,
104) -> *mut [T] {
105 let ptr = ptr as *mut T;
106 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
108 crate::intrinsics::aggregate_raw_ptr(ptr, len)
109}
110
111#[stable(feature = "slice_get_slice", since = "1.28.0")]
116#[rustc_diagnostic_item = "SliceIndex"]
117#[rustc_on_unimplemented(
118 on(T = "str", label = "string indices are ranges of `usize`",),
119 on(
120 all(any(T = "str", T = "&str", T = "alloc::string::String"), Self = "{integer}"),
121 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
122 for more information, see chapter 8 in The Book: \
123 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
124 ),
125 message = "the type `{T}` cannot be indexed by `{Self}`",
126 label = "slice indices are of type `usize` or ranges of `usize`"
127)]
128#[rustc_const_unstable(feature = "const_index", issue = "143775")]
129pub impl(crate) const unsafe trait SliceIndex<T: ?Sized> {
130 #[stable(feature = "slice_get_slice", since = "1.28.0")]
132 type Output: ?Sized;
133
134 #[unstable(feature = "slice_index_methods", issue = "none")]
137 fn get(self, slice: &T) -> Option<&Self::Output>;
138
139 #[unstable(feature = "slice_index_methods", issue = "none")]
142 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
143
144 #[unstable(feature = "slice_index_methods", issue = "none")]
154 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
155
156 #[unstable(feature = "slice_index_methods", issue = "none")]
166 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
167
168 #[unstable(feature = "slice_index_methods", issue = "none")]
171 #[track_caller]
172 fn index(self, slice: &T) -> &Self::Output;
173
174 #[unstable(feature = "slice_index_methods", issue = "none")]
177 #[track_caller]
178 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
179}
180
181#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
183#[rustc_const_unstable(feature = "const_index", issue = "143775")]
184const unsafe impl<T> SliceIndex<[T]> for usize {
185 type Output = T;
186
187 #[ferrocene::prevalidated]
188 #[inline]
189 fn get(self, slice: &[T]) -> Option<&T> {
190 if self < slice.len() {
191 unsafe { Some(slice_get_unchecked(slice, self)) }
193 } else {
194 None
195 }
196 }
197
198 #[ferrocene::prevalidated]
199 #[inline]
200 #[rustc_no_writable]
201 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
202 if self < slice.len() {
203 unsafe { Some(slice_get_unchecked(slice, self)) }
205 } else {
206 None
207 }
208 }
209
210 #[inline]
211 #[track_caller]
212 #[ferrocene::prevalidated]
213 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
214 assert_unsafe_precondition!(
215 check_language_ub, "slice::get_unchecked requires that the index is within the slice",
217 (this: usize = self, len: usize = slice.len()) => this < len
218 );
219 unsafe {
224 crate::intrinsics::assume(self < slice.len());
227 slice_get_unchecked(slice, self)
228 }
229 }
230
231 #[inline]
232 #[track_caller]
233 #[ferrocene::prevalidated]
234 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
235 assert_unsafe_precondition!(
236 check_library_ub,
237 "slice::get_unchecked_mut requires that the index is within the slice",
238 (this: usize = self, len: usize = slice.len()) => this < len
239 );
240 unsafe { slice_get_unchecked(slice, self) }
242 }
243
244 #[inline]
245 #[ferrocene::prevalidated]
246 fn index(self, slice: &[T]) -> &T {
247 &(*slice)[self]
249 }
250
251 #[ferrocene::prevalidated]
252 #[inline]
253 #[rustc_no_writable]
254 fn index_mut(self, slice: &mut [T]) -> &mut T {
255 &mut (*slice)[self]
257 }
258}
259
260#[rustc_const_unstable(feature = "const_index", issue = "143775")]
263const unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
264 type Output = [T];
265
266 #[inline]
267 #[ferrocene::prevalidated]
268 fn get(self, slice: &[T]) -> Option<&[T]> {
269 if self.end() <= slice.len() {
270 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
272 } else {
273 None
274 }
275 }
276
277 #[ferrocene::prevalidated]
278 #[inline]
279 #[rustc_no_writable]
280 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
281 if self.end() <= slice.len() {
282 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
284 } else {
285 None
286 }
287 }
288
289 #[inline]
290 #[track_caller]
291 #[ferrocene::prevalidated]
292 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
293 assert_unsafe_precondition!(
294 check_library_ub,
295 "slice::get_unchecked requires that the index is within the slice",
296 (end: usize = self.end(), len: usize = slice.len()) => end <= len
297 );
298 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
303 }
304
305 #[inline]
306 #[track_caller]
307 #[ferrocene::prevalidated]
308 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
309 assert_unsafe_precondition!(
310 check_library_ub,
311 "slice::get_unchecked_mut requires that the index is within the slice",
312 (end: usize = self.end(), len: usize = slice.len()) => end <= len
313 );
314
315 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
317 }
318
319 #[inline]
320 #[ferrocene::prevalidated]
321 fn index(self, slice: &[T]) -> &[T] {
322 if self.end() <= slice.len() {
323 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
325 } else {
326 slice_index_fail(self.start(), self.end(), slice.len())
327 }
328 }
329
330 #[ferrocene::prevalidated]
331 #[inline]
332 #[rustc_no_writable]
333 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
334 if self.end() <= slice.len() {
335 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
337 } else {
338 slice_index_fail(self.start(), self.end(), slice.len())
339 }
340 }
341}
342
343#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
347#[rustc_const_unstable(feature = "const_index", issue = "143775")]
348const unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
349 type Output = [T];
350
351 #[inline]
352 #[ferrocene::prevalidated]
353 fn get(self, slice: &[T]) -> Option<&[T]> {
354 if let Some(new_len) = usize::checked_sub(self.end, self.start)
356 && self.end <= slice.len()
357 {
358 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
360 } else {
361 None
362 }
363 }
364
365 #[ferrocene::prevalidated]
366 #[inline]
367 #[rustc_no_writable]
368 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
369 if let Some(new_len) = usize::checked_sub(self.end, self.start)
370 && self.end <= slice.len()
371 {
372 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
374 } else {
375 None
376 }
377 }
378
379 #[inline]
380 #[track_caller]
381 #[ferrocene::prevalidated]
382 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
383 assert_unsafe_precondition!(
384 check_library_ub,
385 "slice::get_unchecked requires that the range is within the slice",
386 (
387 start: usize = self.start,
388 end: usize = self.end,
389 len: usize = slice.len()
390 ) => end >= start && end <= len
391 );
392
393 unsafe {
398 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
401 get_offset_len_noubcheck(slice, self.start, new_len)
402 }
403 }
404
405 #[inline]
406 #[track_caller]
407 #[ferrocene::prevalidated]
408 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
409 assert_unsafe_precondition!(
410 check_library_ub,
411 "slice::get_unchecked_mut requires that the range is within the slice",
412 (
413 start: usize = self.start,
414 end: usize = self.end,
415 len: usize = slice.len()
416 ) => end >= start && end <= len
417 );
418 unsafe {
420 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
421 get_offset_len_mut_noubcheck(slice, self.start, new_len)
422 }
423 }
424
425 #[inline(always)]
426 #[ferrocene::prevalidated]
427 fn index(self, slice: &[T]) -> &[T] {
428 if let Some(new_len) = usize::checked_sub(self.end, self.start)
430 && self.end <= slice.len()
431 {
432 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
434 } else {
435 slice_index_fail(self.start, self.end, slice.len())
436 }
437 }
438
439 #[ferrocene::prevalidated]
440 #[inline]
441 #[rustc_no_writable]
442 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
443 if let Some(new_len) = usize::checked_sub(self.end, self.start)
445 && self.end <= slice.len()
446 {
447 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
449 } else {
450 slice_index_fail(self.start, self.end, slice.len())
451 }
452 }
453}
454
455#[stable(feature = "new_range_api", since = "1.96.0")]
456#[rustc_const_unstable(feature = "const_index", issue = "143775")]
457const unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
458 type Output = [T];
459
460 #[inline]
461 fn get(self, slice: &[T]) -> Option<&[T]> {
462 ops::Range::from(self).get(slice)
463 }
464
465 #[inline]
466 #[rustc_no_writable]
467 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
468 ops::Range::from(self).get_mut(slice)
469 }
470
471 #[inline]
472 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
473 unsafe { ops::Range::from(self).get_unchecked(slice) }
475 }
476
477 #[inline]
478 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
479 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
481 }
482
483 #[inline(always)]
484 fn index(self, slice: &[T]) -> &[T] {
485 ops::Range::from(self).index(slice)
486 }
487
488 #[inline]
489 #[rustc_no_writable]
490 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
491 ops::Range::from(self).index_mut(slice)
492 }
493}
494
495#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
497#[rustc_const_unstable(feature = "const_index", issue = "143775")]
498const unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
499 type Output = [T];
500
501 #[inline]
502 #[ferrocene::prevalidated]
503 fn get(self, slice: &[T]) -> Option<&[T]> {
504 (0..self.end).get(slice)
505 }
506
507 #[ferrocene::prevalidated]
508 #[inline]
509 #[rustc_no_writable]
510 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
511 (0..self.end).get_mut(slice)
512 }
513
514 #[inline]
515 #[ferrocene::prevalidated]
516 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
517 unsafe { (0..self.end).get_unchecked(slice) }
519 }
520
521 #[inline]
522 #[ferrocene::prevalidated]
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 #[ferrocene::prevalidated]
530 fn index(self, slice: &[T]) -> &[T] {
531 (0..self.end).index(slice)
532 }
533
534 #[ferrocene::prevalidated]
535 #[inline]
536 #[rustc_no_writable]
537 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
538 (0..self.end).index_mut(slice)
539 }
540}
541
542#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
544#[rustc_const_unstable(feature = "const_index", issue = "143775")]
545const unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
546 type Output = [T];
547
548 #[inline]
549 #[ferrocene::prevalidated]
550 fn get(self, slice: &[T]) -> Option<&[T]> {
551 (self.start..slice.len()).get(slice)
552 }
553
554 #[ferrocene::prevalidated]
555 #[inline]
556 #[rustc_no_writable]
557 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
558 (self.start..slice.len()).get_mut(slice)
559 }
560
561 #[inline]
562 #[ferrocene::prevalidated]
563 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
564 unsafe { (self.start..slice.len()).get_unchecked(slice) }
566 }
567
568 #[inline]
569 #[ferrocene::prevalidated]
570 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
571 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
573 }
574
575 #[inline]
576 #[ferrocene::prevalidated]
577 fn index(self, slice: &[T]) -> &[T] {
578 if self.start > slice.len() {
579 slice_index_fail(self.start, slice.len(), slice.len())
580 }
581 unsafe {
583 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
584 &*get_offset_len_noubcheck(slice, self.start, new_len)
585 }
586 }
587
588 #[ferrocene::prevalidated]
589 #[inline]
590 #[rustc_no_writable]
591 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
592 if self.start > slice.len() {
593 slice_index_fail(self.start, slice.len(), slice.len())
594 }
595 unsafe {
597 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
598 &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)
599 }
600 }
601}
602
603#[stable(feature = "new_range_from_api", since = "1.96.0")]
604#[rustc_const_unstable(feature = "const_index", issue = "143775")]
605const unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
606 type Output = [T];
607
608 #[inline]
609 fn get(self, slice: &[T]) -> Option<&[T]> {
610 ops::RangeFrom::from(self).get(slice)
611 }
612
613 #[inline]
614 #[rustc_no_writable]
615 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
616 ops::RangeFrom::from(self).get_mut(slice)
617 }
618
619 #[inline]
620 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
621 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
623 }
624
625 #[inline]
626 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
627 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
629 }
630
631 #[inline]
632 fn index(self, slice: &[T]) -> &[T] {
633 ops::RangeFrom::from(self).index(slice)
634 }
635
636 #[inline]
637 #[rustc_no_writable]
638 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
639 ops::RangeFrom::from(self).index_mut(slice)
640 }
641}
642
643#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
644#[rustc_const_unstable(feature = "const_index", issue = "143775")]
645const unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
646 type Output = [T];
647
648 #[inline]
649 #[ferrocene::prevalidated]
650 fn get(self, slice: &[T]) -> Option<&[T]> {
651 Some(slice)
652 }
653
654 #[ferrocene::prevalidated]
655 #[inline]
656 #[rustc_no_writable]
657 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
658 Some(slice)
659 }
660
661 #[inline]
662 #[ferrocene::prevalidated]
663 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
664 slice
665 }
666
667 #[inline]
668 #[ferrocene::prevalidated]
669 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
670 slice
671 }
672
673 #[inline]
674 #[ferrocene::prevalidated]
675 fn index(self, slice: &[T]) -> &[T] {
676 slice
677 }
678
679 #[ferrocene::prevalidated]
680 #[inline]
681 #[rustc_no_writable]
682 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
683 slice
684 }
685}
686
687#[stable(feature = "inclusive_range", since = "1.26.0")]
691#[rustc_const_unstable(feature = "const_index", issue = "143775")]
692const unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
693 type Output = [T];
694
695 #[inline]
696 #[ferrocene::prevalidated]
697 fn get(self, slice: &[T]) -> Option<&[T]> {
698 if *self.end() >= slice.len() { None } else { self.into_slice_range().get(slice) }
699 }
700
701 #[ferrocene::prevalidated]
702 #[inline]
703 #[rustc_no_writable]
704 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
705 if *self.end() >= slice.len() { None } else { self.into_slice_range().get_mut(slice) }
706 }
707
708 #[inline]
709 #[ferrocene::prevalidated]
710 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
711 unsafe { self.into_slice_range().get_unchecked(slice) }
713 }
714
715 #[inline]
716 #[ferrocene::prevalidated]
717 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
718 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
720 }
721
722 #[inline]
723 #[ferrocene::prevalidated]
724 fn index(self, slice: &[T]) -> &[T] {
725 let Self { mut start, mut end, exhausted } = self;
726 let len = slice.len();
727 if end < len {
728 end = end + 1;
729 start = if exhausted { end } else { start };
730 if let Some(new_len) = usize::checked_sub(end, start) {
731 unsafe { return &*get_offset_len_noubcheck(slice, start, new_len) }
733 }
734 }
735 slice_index_fail(start, end, slice.len())
736 }
737
738 #[ferrocene::prevalidated]
739 #[inline]
740 #[rustc_no_writable]
741 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
742 let Self { mut start, mut end, exhausted } = self;
743 let len = slice.len();
744 if end < len {
745 end = end + 1;
746 start = if exhausted { end } else { start };
747 if let Some(new_len) = usize::checked_sub(end, start) {
748 unsafe { return &mut *get_offset_len_mut_noubcheck(slice, start, new_len) }
750 }
751 }
752 slice_index_fail(start, end, slice.len())
753 }
754}
755
756#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
757#[rustc_const_unstable(feature = "const_index", issue = "143775")]
758const unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
759 type Output = [T];
760
761 #[inline]
762 fn get(self, slice: &[T]) -> Option<&[T]> {
763 ops::RangeInclusive::from(self).get(slice)
764 }
765
766 #[inline]
767 #[rustc_no_writable]
768 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
769 ops::RangeInclusive::from(self).get_mut(slice)
770 }
771
772 #[inline]
773 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
774 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
776 }
777
778 #[inline]
779 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
780 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
782 }
783
784 #[inline]
785 fn index(self, slice: &[T]) -> &[T] {
786 ops::RangeInclusive::from(self).index(slice)
787 }
788
789 #[inline]
790 #[rustc_no_writable]
791 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
792 ops::RangeInclusive::from(self).index_mut(slice)
793 }
794}
795
796#[stable(feature = "inclusive_range", since = "1.26.0")]
798#[rustc_const_unstable(feature = "const_index", issue = "143775")]
799const unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
800 type Output = [T];
801
802 #[inline]
803 #[ferrocene::prevalidated]
804 fn get(self, slice: &[T]) -> Option<&[T]> {
805 (0..=self.end).get(slice)
806 }
807
808 #[ferrocene::prevalidated]
809 #[inline]
810 #[rustc_no_writable]
811 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
812 (0..=self.end).get_mut(slice)
813 }
814
815 #[inline]
816 #[ferrocene::prevalidated]
817 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
818 unsafe { (0..=self.end).get_unchecked(slice) }
820 }
821
822 #[inline]
823 #[ferrocene::prevalidated]
824 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
825 unsafe { (0..=self.end).get_unchecked_mut(slice) }
827 }
828
829 #[inline]
830 #[ferrocene::prevalidated]
831 fn index(self, slice: &[T]) -> &[T] {
832 (0..=self.end).index(slice)
833 }
834
835 #[ferrocene::prevalidated]
836 #[inline]
837 #[rustc_no_writable]
838 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
839 (0..=self.end).index_mut(slice)
840 }
841}
842
843#[stable(feature = "new_range_to_inclusive_api", since = "1.96.0")]
845#[rustc_const_unstable(feature = "const_index", issue = "143775")]
846const unsafe impl<T> SliceIndex<[T]> for range::RangeToInclusive<usize> {
847 type Output = [T];
848
849 #[inline]
850 fn get(self, slice: &[T]) -> Option<&[T]> {
851 (0..=self.last).get(slice)
852 }
853
854 #[inline]
855 #[rustc_no_writable]
856 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
857 (0..=self.last).get_mut(slice)
858 }
859
860 #[inline]
861 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
862 unsafe { (0..=self.last).get_unchecked(slice) }
864 }
865
866 #[inline]
867 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
868 unsafe { (0..=self.last).get_unchecked_mut(slice) }
870 }
871
872 #[inline]
873 fn index(self, slice: &[T]) -> &[T] {
874 (0..=self.last).index(slice)
875 }
876
877 #[inline]
878 #[rustc_no_writable]
879 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
880 (0..=self.last).index_mut(slice)
881 }
882}
883
884#[track_caller]
946#[unstable(feature = "slice_range", issue = "76393")]
947#[must_use]
948#[rustc_const_unstable(feature = "const_range", issue = "none")]
949pub const fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
950where
951 R: [const] ops::RangeBounds<usize> + [const] Destruct,
952{
953 let len = bounds.end;
954 into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
955}
956
957#[unstable(feature = "slice_range", issue = "76393")]
988#[must_use]
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 try_into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
995}
996
997#[ferrocene::prevalidated]
1000pub(crate) const fn into_range_unchecked(
1001 len: usize,
1002 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1003) -> ops::Range<usize> {
1004 use ops::Bound;
1005 let start = match start {
1006 Bound::Included(i) => i,
1007 Bound::Excluded(i) => i + 1,
1008 Bound::Unbounded => 0,
1009 };
1010 let end = match end {
1011 Bound::Included(i) => i + 1,
1012 Bound::Excluded(i) => i,
1013 Bound::Unbounded => len,
1014 };
1015 start..end
1016}
1017
1018#[rustc_const_unstable(feature = "const_range", issue = "none")]
1021#[inline]
1022#[ferrocene::prevalidated]
1023pub(crate) const fn try_into_slice_range(
1024 len: usize,
1025 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1026) -> Option<ops::Range<usize>> {
1027 let end = match end {
1028 ops::Bound::Included(end) if end >= len => return None,
1029 ops::Bound::Included(end) => end + 1,
1031
1032 ops::Bound::Excluded(end) if end > len => return None,
1033 ops::Bound::Excluded(end) => end,
1034
1035 ops::Bound::Unbounded => len,
1036 };
1037
1038 let start = match start {
1039 ops::Bound::Excluded(start) if start >= end => return None,
1040 ops::Bound::Excluded(start) => start + 1,
1042
1043 ops::Bound::Included(start) if start > end => return None,
1044 ops::Bound::Included(start) => start,
1045
1046 ops::Bound::Unbounded => 0,
1047 };
1048
1049 Some(start..end)
1050}
1051
1052#[inline]
1055#[ferrocene::prevalidated]
1056pub(crate) const fn into_slice_range(
1057 len: usize,
1058 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1059) -> ops::Range<usize> {
1060 let end = match end {
1061 ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
1062 ops::Bound::Included(end) => end + 1,
1064
1065 ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
1066 ops::Bound::Excluded(end) => end,
1067
1068 ops::Bound::Unbounded => len,
1069 };
1070
1071 let start = match start {
1072 ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
1073 ops::Bound::Excluded(start) => start + 1,
1075
1076 ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
1077 ops::Bound::Included(start) => start,
1078
1079 ops::Bound::Unbounded => 0,
1080 };
1081
1082 start..end
1083}
1084
1085#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1086unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1087 type Output = [T];
1088
1089 #[inline]
1090 #[ferrocene::prevalidated]
1091 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1092 try_into_slice_range(slice.len(), self)?.get(slice)
1093 }
1094
1095 #[ferrocene::prevalidated]
1096 #[inline]
1097 #[rustc_no_writable]
1098 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1099 try_into_slice_range(slice.len(), self)?.get_mut(slice)
1100 }
1101
1102 #[inline]
1103 #[ferrocene::prevalidated]
1104 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1105 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1107 }
1108
1109 #[inline]
1110 #[ferrocene::prevalidated]
1111 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1112 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1114 }
1115
1116 #[inline]
1117 #[ferrocene::prevalidated]
1118 fn index(self, slice: &[T]) -> &Self::Output {
1119 into_slice_range(slice.len(), self).index(slice)
1120 }
1121
1122 #[ferrocene::prevalidated]
1123 #[inline]
1124 #[rustc_no_writable]
1125 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1126 into_slice_range(slice.len(), self).index_mut(slice)
1127 }
1128}