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 #[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")]
26impl<T, I> const ops::IndexMut<I> for [T]
27where
28 I: [const] SliceIndex<[T]>,
29{
30 #[inline(always)]
31 #[ferrocene::prevalidated]
32 fn index_mut(&mut self, index: I) -> &mut I::Output {
33 index.index_mut(self)
34 }
35}
36
37#[cfg_attr(not(panic = "immediate-abort"), inline(never), cold)]
38#[cfg_attr(panic = "immediate-abort", inline)]
39#[track_caller]
40#[ferrocene::prevalidated]
41const fn slice_index_fail(start: usize, end: usize, len: usize) -> ! {
42 if start > len {
43 const_panic!(
44 "slice start index is out of range for slice",
45 "range start index {start} out of range for slice of length {len}",
46 start: usize,
47 len: usize,
48 )
49 }
50
51 if end > len {
52 const_panic!(
53 "slice end index is out of range for slice",
54 "range end index {end} out of range for slice of length {len}",
55 end: usize,
56 len: usize,
57 )
58 }
59
60 if start > end {
61 const_panic!(
62 "slice index start is larger than end",
63 "slice index starts at {start} but ends at {end}",
64 start: usize,
65 end: usize,
66 )
67 }
68
69 const_panic!(
72 "slice end index is out of range for slice",
73 "range end index {end} out of range for slice of length {len}",
74 end: usize,
75 len: usize,
76 )
77}
78
79#[inline(always)]
85#[ferrocene::prevalidated]
86const unsafe fn get_offset_len_noubcheck<T>(
87 ptr: *const [T],
88 offset: usize,
89 len: usize,
90) -> *const [T] {
91 let ptr = ptr as *const T;
92 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
94 crate::intrinsics::aggregate_raw_ptr(ptr, len)
95}
96
97#[inline(always)]
98#[ferrocene::prevalidated]
99const unsafe fn get_offset_len_mut_noubcheck<T>(
100 ptr: *mut [T],
101 offset: usize,
102 len: usize,
103) -> *mut [T] {
104 let ptr = ptr as *mut T;
105 let ptr = unsafe { crate::intrinsics::offset(ptr, offset) };
107 crate::intrinsics::aggregate_raw_ptr(ptr, len)
108}
109
110mod private_slice_index {
111 use super::{ops, range};
112
113 #[stable(feature = "slice_get_slice", since = "1.28.0")]
114 pub trait Sealed {}
115
116 #[stable(feature = "slice_get_slice", since = "1.28.0")]
117 impl Sealed for usize {}
118 #[stable(feature = "slice_get_slice", since = "1.28.0")]
119 impl Sealed for ops::Range<usize> {}
120 #[stable(feature = "slice_get_slice", since = "1.28.0")]
121 impl Sealed for ops::RangeTo<usize> {}
122 #[stable(feature = "slice_get_slice", since = "1.28.0")]
123 impl Sealed for ops::RangeFrom<usize> {}
124 #[stable(feature = "slice_get_slice", since = "1.28.0")]
125 impl Sealed for ops::RangeFull {}
126 #[stable(feature = "slice_get_slice", since = "1.28.0")]
127 impl Sealed for ops::RangeInclusive<usize> {}
128 #[stable(feature = "slice_get_slice", since = "1.28.0")]
129 impl Sealed for ops::RangeToInclusive<usize> {}
130 #[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
131 impl Sealed for (ops::Bound<usize>, ops::Bound<usize>) {}
132
133 #[unstable(feature = "new_range_api", issue = "125687")]
134 impl Sealed for range::Range<usize> {}
135 #[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
136 impl Sealed for range::RangeInclusive<usize> {}
137 #[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
138 impl Sealed for range::RangeToInclusive<usize> {}
139 #[unstable(feature = "new_range_api", issue = "125687")]
140 impl Sealed for range::RangeFrom<usize> {}
141
142 impl Sealed for ops::IndexRange {}
143
144 #[unstable(feature = "sliceindex_wrappers", issue = "146179")]
145 impl Sealed for crate::index::Last {}
146 #[unstable(feature = "sliceindex_wrappers", issue = "146179")]
147 impl<T> Sealed for crate::index::Clamp<T> where T: Sealed {}
148}
149
150#[stable(feature = "slice_get_slice", since = "1.28.0")]
155#[rustc_diagnostic_item = "SliceIndex"]
156#[rustc_on_unimplemented(
157 on(T = "str", label = "string indices are ranges of `usize`",),
158 on(
159 all(any(T = "str", T = "&str", T = "alloc::string::String"), Self = "{integer}"),
160 note = "you can use `.chars().nth()` or `.bytes().nth()`\n\
161 for more information, see chapter 8 in The Book: \
162 <https://doc.rust-lang.org/book/ch08-02-strings.html#indexing-into-strings>"
163 ),
164 message = "the type `{T}` cannot be indexed by `{Self}`",
165 label = "slice indices are of type `usize` or ranges of `usize`"
166)]
167#[rustc_const_unstable(feature = "const_index", issue = "143775")]
168pub const unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
169 #[stable(feature = "slice_get_slice", since = "1.28.0")]
171 type Output: ?Sized;
172
173 #[unstable(feature = "slice_index_methods", issue = "none")]
176 fn get(self, slice: &T) -> Option<&Self::Output>;
177
178 #[unstable(feature = "slice_index_methods", issue = "none")]
181 fn get_mut(self, slice: &mut T) -> Option<&mut Self::Output>;
182
183 #[unstable(feature = "slice_index_methods", issue = "none")]
191 unsafe fn get_unchecked(self, slice: *const T) -> *const Self::Output;
192
193 #[unstable(feature = "slice_index_methods", issue = "none")]
201 unsafe fn get_unchecked_mut(self, slice: *mut T) -> *mut Self::Output;
202
203 #[unstable(feature = "slice_index_methods", issue = "none")]
206 #[track_caller]
207 fn index(self, slice: &T) -> &Self::Output;
208
209 #[unstable(feature = "slice_index_methods", issue = "none")]
212 #[track_caller]
213 fn index_mut(self, slice: &mut T) -> &mut Self::Output;
214}
215
216#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
218#[rustc_const_unstable(feature = "const_index", issue = "143775")]
219unsafe impl<T> const SliceIndex<[T]> for usize {
220 type Output = T;
221
222 #[inline]
223 #[ferrocene::prevalidated]
224 fn get(self, slice: &[T]) -> Option<&T> {
225 if self < slice.len() {
226 unsafe { Some(slice_get_unchecked(slice, self)) }
228 } else {
229 None
230 }
231 }
232
233 #[inline]
234 #[ferrocene::prevalidated]
235 fn get_mut(self, slice: &mut [T]) -> Option<&mut T> {
236 if self < slice.len() {
237 unsafe { Some(slice_get_unchecked(slice, self)) }
239 } else {
240 None
241 }
242 }
243
244 #[inline]
245 #[track_caller]
246 #[ferrocene::prevalidated]
247 unsafe fn get_unchecked(self, slice: *const [T]) -> *const T {
248 assert_unsafe_precondition!(
249 check_language_ub, "slice::get_unchecked requires that the index is within the slice",
251 (this: usize = self, len: usize = slice.len()) => this < len
252 );
253 unsafe {
258 crate::intrinsics::assume(self < slice.len());
261 slice_get_unchecked(slice, self)
262 }
263 }
264
265 #[inline]
266 #[track_caller]
267 #[ferrocene::prevalidated]
268 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut T {
269 assert_unsafe_precondition!(
270 check_library_ub,
271 "slice::get_unchecked_mut requires that the index is within the slice",
272 (this: usize = self, len: usize = slice.len()) => this < len
273 );
274 unsafe { slice_get_unchecked(slice, self) }
276 }
277
278 #[inline]
279 #[ferrocene::prevalidated]
280 fn index(self, slice: &[T]) -> &T {
281 &(*slice)[self]
283 }
284
285 #[inline]
286 #[ferrocene::prevalidated]
287 fn index_mut(self, slice: &mut [T]) -> &mut T {
288 &mut (*slice)[self]
290 }
291}
292
293#[rustc_const_unstable(feature = "const_index", issue = "143775")]
296unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
297 type Output = [T];
298
299 #[inline]
300 #[ferrocene::prevalidated]
301 fn get(self, slice: &[T]) -> Option<&[T]> {
302 if self.end() <= slice.len() {
303 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start(), self.len())) }
305 } else {
306 None
307 }
308 }
309
310 #[inline]
311 #[ferrocene::prevalidated]
312 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
313 if self.end() <= slice.len() {
314 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len())) }
316 } else {
317 None
318 }
319 }
320
321 #[inline]
322 #[track_caller]
323 #[ferrocene::prevalidated]
324 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
325 assert_unsafe_precondition!(
326 check_library_ub,
327 "slice::get_unchecked requires that the index is within the slice",
328 (end: usize = self.end(), len: usize = slice.len()) => end <= len
329 );
330 unsafe { get_offset_len_noubcheck(slice, self.start(), self.len()) }
335 }
336
337 #[inline]
338 #[track_caller]
339 #[ferrocene::prevalidated]
340 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
341 assert_unsafe_precondition!(
342 check_library_ub,
343 "slice::get_unchecked_mut requires that the index is within the slice",
344 (end: usize = self.end(), len: usize = slice.len()) => end <= len
345 );
346
347 unsafe { get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
349 }
350
351 #[inline]
352 #[ferrocene::prevalidated]
353 fn index(self, slice: &[T]) -> &[T] {
354 if self.end() <= slice.len() {
355 unsafe { &*get_offset_len_noubcheck(slice, self.start(), self.len()) }
357 } else {
358 slice_index_fail(self.start(), self.end(), slice.len())
359 }
360 }
361
362 #[inline]
363 #[ferrocene::prevalidated]
364 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
365 if self.end() <= slice.len() {
366 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start(), self.len()) }
368 } else {
369 slice_index_fail(self.start(), self.end(), slice.len())
370 }
371 }
372}
373
374#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
378#[rustc_const_unstable(feature = "const_index", issue = "143775")]
379unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
380 type Output = [T];
381
382 #[inline]
383 #[ferrocene::prevalidated]
384 fn get(self, slice: &[T]) -> Option<&[T]> {
385 if let Some(new_len) = usize::checked_sub(self.end, self.start)
387 && self.end <= slice.len()
388 {
389 unsafe { Some(&*get_offset_len_noubcheck(slice, self.start, new_len)) }
391 } else {
392 None
393 }
394 }
395
396 #[inline]
397 #[ferrocene::prevalidated]
398 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
399 if let Some(new_len) = usize::checked_sub(self.end, self.start)
400 && self.end <= slice.len()
401 {
402 unsafe { Some(&mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)) }
404 } else {
405 None
406 }
407 }
408
409 #[inline]
410 #[track_caller]
411 #[ferrocene::prevalidated]
412 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
413 assert_unsafe_precondition!(
414 check_library_ub,
415 "slice::get_unchecked requires that the range is within the slice",
416 (
417 start: usize = self.start,
418 end: usize = self.end,
419 len: usize = slice.len()
420 ) => end >= start && end <= len
421 );
422
423 unsafe {
428 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
431 get_offset_len_noubcheck(slice, self.start, new_len)
432 }
433 }
434
435 #[inline]
436 #[track_caller]
437 #[ferrocene::prevalidated]
438 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
439 assert_unsafe_precondition!(
440 check_library_ub,
441 "slice::get_unchecked_mut requires that the range is within the slice",
442 (
443 start: usize = self.start,
444 end: usize = self.end,
445 len: usize = slice.len()
446 ) => end >= start && end <= len
447 );
448 unsafe {
450 let new_len = crate::intrinsics::unchecked_sub(self.end, self.start);
451 get_offset_len_mut_noubcheck(slice, self.start, new_len)
452 }
453 }
454
455 #[inline(always)]
456 #[ferrocene::prevalidated]
457 fn index(self, slice: &[T]) -> &[T] {
458 if let Some(new_len) = usize::checked_sub(self.end, self.start)
460 && self.end <= slice.len()
461 {
462 unsafe { &*get_offset_len_noubcheck(slice, self.start, new_len) }
464 } else {
465 slice_index_fail(self.start, self.end, slice.len())
466 }
467 }
468
469 #[inline]
470 #[ferrocene::prevalidated]
471 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
472 if let Some(new_len) = usize::checked_sub(self.end, self.start)
474 && self.end <= slice.len()
475 {
476 unsafe { &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len) }
478 } else {
479 slice_index_fail(self.start, self.end, slice.len())
480 }
481 }
482}
483
484#[unstable(feature = "new_range_api", issue = "125687")]
485#[rustc_const_unstable(feature = "const_index", issue = "143775")]
486unsafe impl<T> const SliceIndex<[T]> for range::Range<usize> {
487 type Output = [T];
488
489 #[inline]
490 fn get(self, slice: &[T]) -> Option<&[T]> {
491 ops::Range::from(self).get(slice)
492 }
493
494 #[inline]
495 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
496 ops::Range::from(self).get_mut(slice)
497 }
498
499 #[inline]
500 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
501 unsafe { ops::Range::from(self).get_unchecked(slice) }
503 }
504
505 #[inline]
506 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
507 unsafe { ops::Range::from(self).get_unchecked_mut(slice) }
509 }
510
511 #[inline(always)]
512 fn index(self, slice: &[T]) -> &[T] {
513 ops::Range::from(self).index(slice)
514 }
515
516 #[inline]
517 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
518 ops::Range::from(self).index_mut(slice)
519 }
520}
521
522#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
524#[rustc_const_unstable(feature = "const_index", issue = "143775")]
525unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
526 type Output = [T];
527
528 #[inline]
529 #[ferrocene::prevalidated]
530 fn get(self, slice: &[T]) -> Option<&[T]> {
531 (0..self.end).get(slice)
532 }
533
534 #[inline]
535 #[ferrocene::prevalidated]
536 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
537 (0..self.end).get_mut(slice)
538 }
539
540 #[inline]
541 #[ferrocene::prevalidated]
542 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
543 unsafe { (0..self.end).get_unchecked(slice) }
545 }
546
547 #[inline]
548 #[ferrocene::prevalidated]
549 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
550 unsafe { (0..self.end).get_unchecked_mut(slice) }
552 }
553
554 #[inline(always)]
555 #[ferrocene::prevalidated]
556 fn index(self, slice: &[T]) -> &[T] {
557 (0..self.end).index(slice)
558 }
559
560 #[inline]
561 #[ferrocene::prevalidated]
562 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
563 (0..self.end).index_mut(slice)
564 }
565}
566
567#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
569#[rustc_const_unstable(feature = "const_index", issue = "143775")]
570unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
571 type Output = [T];
572
573 #[inline]
574 #[ferrocene::prevalidated]
575 fn get(self, slice: &[T]) -> Option<&[T]> {
576 (self.start..slice.len()).get(slice)
577 }
578
579 #[inline]
580 #[ferrocene::prevalidated]
581 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
582 (self.start..slice.len()).get_mut(slice)
583 }
584
585 #[inline]
586 #[ferrocene::prevalidated]
587 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
588 unsafe { (self.start..slice.len()).get_unchecked(slice) }
590 }
591
592 #[inline]
593 #[ferrocene::prevalidated]
594 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
595 unsafe { (self.start..slice.len()).get_unchecked_mut(slice) }
597 }
598
599 #[inline]
600 #[ferrocene::prevalidated]
601 fn index(self, slice: &[T]) -> &[T] {
602 if self.start > slice.len() {
603 slice_index_fail(self.start, slice.len(), slice.len())
604 }
605 unsafe {
607 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
608 &*get_offset_len_noubcheck(slice, self.start, new_len)
609 }
610 }
611
612 #[inline]
613 #[ferrocene::prevalidated]
614 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
615 if self.start > slice.len() {
616 slice_index_fail(self.start, slice.len(), slice.len())
617 }
618 unsafe {
620 let new_len = crate::intrinsics::unchecked_sub(slice.len(), self.start);
621 &mut *get_offset_len_mut_noubcheck(slice, self.start, new_len)
622 }
623 }
624}
625
626#[unstable(feature = "new_range_api", issue = "125687")]
627#[rustc_const_unstable(feature = "const_index", issue = "143775")]
628unsafe impl<T> const SliceIndex<[T]> for range::RangeFrom<usize> {
629 type Output = [T];
630
631 #[inline]
632 fn get(self, slice: &[T]) -> Option<&[T]> {
633 ops::RangeFrom::from(self).get(slice)
634 }
635
636 #[inline]
637 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
638 ops::RangeFrom::from(self).get_mut(slice)
639 }
640
641 #[inline]
642 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
643 unsafe { ops::RangeFrom::from(self).get_unchecked(slice) }
645 }
646
647 #[inline]
648 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
649 unsafe { ops::RangeFrom::from(self).get_unchecked_mut(slice) }
651 }
652
653 #[inline]
654 fn index(self, slice: &[T]) -> &[T] {
655 ops::RangeFrom::from(self).index(slice)
656 }
657
658 #[inline]
659 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
660 ops::RangeFrom::from(self).index_mut(slice)
661 }
662}
663
664#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
665#[rustc_const_unstable(feature = "const_index", issue = "143775")]
666unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
667 type Output = [T];
668
669 #[inline]
670 #[ferrocene::prevalidated]
671 fn get(self, slice: &[T]) -> Option<&[T]> {
672 Some(slice)
673 }
674
675 #[inline]
676 #[ferrocene::prevalidated]
677 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
678 Some(slice)
679 }
680
681 #[inline]
682 #[ferrocene::prevalidated]
683 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
684 slice
685 }
686
687 #[inline]
688 #[ferrocene::prevalidated]
689 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
690 slice
691 }
692
693 #[inline]
694 #[ferrocene::prevalidated]
695 fn index(self, slice: &[T]) -> &[T] {
696 slice
697 }
698
699 #[inline]
700 #[ferrocene::prevalidated]
701 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
702 slice
703 }
704}
705
706#[stable(feature = "inclusive_range", since = "1.26.0")]
710#[rustc_const_unstable(feature = "const_index", issue = "143775")]
711unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
712 type Output = [T];
713
714 #[inline]
715 #[ferrocene::prevalidated]
716 fn get(self, slice: &[T]) -> Option<&[T]> {
717 if *self.end() >= slice.len() { None } else { self.into_slice_range().get(slice) }
718 }
719
720 #[inline]
721 #[ferrocene::prevalidated]
722 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
723 if *self.end() >= slice.len() { None } else { self.into_slice_range().get_mut(slice) }
724 }
725
726 #[inline]
727 #[ferrocene::prevalidated]
728 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
729 unsafe { self.into_slice_range().get_unchecked(slice) }
731 }
732
733 #[inline]
734 #[ferrocene::prevalidated]
735 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
736 unsafe { self.into_slice_range().get_unchecked_mut(slice) }
738 }
739
740 #[inline]
741 #[ferrocene::prevalidated]
742 fn index(self, slice: &[T]) -> &[T] {
743 let Self { mut start, mut end, exhausted } = self;
744 let len = slice.len();
745 if end < len {
746 end = end + 1;
747 start = if exhausted { end } else { start };
748 if let Some(new_len) = usize::checked_sub(end, start) {
749 unsafe { return &*get_offset_len_noubcheck(slice, start, new_len) }
751 }
752 }
753 slice_index_fail(start, end, slice.len())
754 }
755
756 #[inline]
757 #[ferrocene::prevalidated]
758 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
759 let Self { mut start, mut end, exhausted } = self;
760 let len = slice.len();
761 if end < len {
762 end = end + 1;
763 start = if exhausted { end } else { start };
764 if let Some(new_len) = usize::checked_sub(end, start) {
765 unsafe { return &mut *get_offset_len_mut_noubcheck(slice, start, new_len) }
767 }
768 }
769 slice_index_fail(start, end, slice.len())
770 }
771}
772
773#[stable(feature = "new_range_inclusive_api", since = "1.95.0")]
774#[rustc_const_unstable(feature = "const_index", issue = "143775")]
775unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
776 type Output = [T];
777
778 #[inline]
779 fn get(self, slice: &[T]) -> Option<&[T]> {
780 ops::RangeInclusive::from(self).get(slice)
781 }
782
783 #[inline]
784 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
785 ops::RangeInclusive::from(self).get_mut(slice)
786 }
787
788 #[inline]
789 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
790 unsafe { ops::RangeInclusive::from(self).get_unchecked(slice) }
792 }
793
794 #[inline]
795 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
796 unsafe { ops::RangeInclusive::from(self).get_unchecked_mut(slice) }
798 }
799
800 #[inline]
801 fn index(self, slice: &[T]) -> &[T] {
802 ops::RangeInclusive::from(self).index(slice)
803 }
804
805 #[inline]
806 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
807 ops::RangeInclusive::from(self).index_mut(slice)
808 }
809}
810
811#[stable(feature = "inclusive_range", since = "1.26.0")]
813#[rustc_const_unstable(feature = "const_index", issue = "143775")]
814unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
815 type Output = [T];
816
817 #[inline]
818 #[ferrocene::prevalidated]
819 fn get(self, slice: &[T]) -> Option<&[T]> {
820 (0..=self.end).get(slice)
821 }
822
823 #[inline]
824 #[ferrocene::prevalidated]
825 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
826 (0..=self.end).get_mut(slice)
827 }
828
829 #[inline]
830 #[ferrocene::prevalidated]
831 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
832 unsafe { (0..=self.end).get_unchecked(slice) }
834 }
835
836 #[inline]
837 #[ferrocene::prevalidated]
838 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
839 unsafe { (0..=self.end).get_unchecked_mut(slice) }
841 }
842
843 #[inline]
844 #[ferrocene::prevalidated]
845 fn index(self, slice: &[T]) -> &[T] {
846 (0..=self.end).index(slice)
847 }
848
849 #[inline]
850 #[ferrocene::prevalidated]
851 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
852 (0..=self.end).index_mut(slice)
853 }
854}
855
856#[stable(feature = "new_range_to_inclusive_api", since = "CURRENT_RUSTC_VERSION")]
858#[rustc_const_unstable(feature = "const_index", issue = "143775")]
859unsafe impl<T> const SliceIndex<[T]> for range::RangeToInclusive<usize> {
860 type Output = [T];
861
862 #[inline]
863 fn get(self, slice: &[T]) -> Option<&[T]> {
864 (0..=self.last).get(slice)
865 }
866
867 #[inline]
868 fn get_mut(self, slice: &mut [T]) -> Option<&mut [T]> {
869 (0..=self.last).get_mut(slice)
870 }
871
872 #[inline]
873 unsafe fn get_unchecked(self, slice: *const [T]) -> *const [T] {
874 unsafe { (0..=self.last).get_unchecked(slice) }
876 }
877
878 #[inline]
879 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut [T] {
880 unsafe { (0..=self.last).get_unchecked_mut(slice) }
882 }
883
884 #[inline]
885 fn index(self, slice: &[T]) -> &[T] {
886 (0..=self.last).index(slice)
887 }
888
889 #[inline]
890 fn index_mut(self, slice: &mut [T]) -> &mut [T] {
891 (0..=self.last).index_mut(slice)
892 }
893}
894
895#[track_caller]
957#[unstable(feature = "slice_range", issue = "76393")]
958#[must_use]
959#[rustc_const_unstable(feature = "const_range", issue = "none")]
960pub const fn range<R>(range: R, bounds: ops::RangeTo<usize>) -> ops::Range<usize>
961where
962 R: [const] ops::RangeBounds<usize> + [const] Destruct,
963{
964 let len = bounds.end;
965 into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
966}
967
968#[unstable(feature = "slice_range", issue = "76393")]
999#[must_use]
1000pub fn try_range<R>(range: R, bounds: ops::RangeTo<usize>) -> Option<ops::Range<usize>>
1001where
1002 R: ops::RangeBounds<usize>,
1003{
1004 let len = bounds.end;
1005 try_into_slice_range(len, (range.start_bound().copied(), range.end_bound().copied()))
1006}
1007
1008#[ferrocene::prevalidated]
1011pub(crate) const fn into_range_unchecked(
1012 len: usize,
1013 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1014) -> ops::Range<usize> {
1015 use ops::Bound;
1016 let start = match start {
1017 Bound::Included(i) => i,
1018 Bound::Excluded(i) => i + 1,
1019 Bound::Unbounded => 0,
1020 };
1021 let end = match end {
1022 Bound::Included(i) => i + 1,
1023 Bound::Excluded(i) => i,
1024 Bound::Unbounded => len,
1025 };
1026 start..end
1027}
1028
1029#[rustc_const_unstable(feature = "const_range", issue = "none")]
1032#[inline]
1033#[ferrocene::prevalidated]
1034pub(crate) const fn try_into_slice_range(
1035 len: usize,
1036 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1037) -> Option<ops::Range<usize>> {
1038 let end = match end {
1039 ops::Bound::Included(end) if end >= len => return None,
1040 ops::Bound::Included(end) => end + 1,
1042
1043 ops::Bound::Excluded(end) if end > len => return None,
1044 ops::Bound::Excluded(end) => end,
1045
1046 ops::Bound::Unbounded => len,
1047 };
1048
1049 let start = match start {
1050 ops::Bound::Excluded(start) if start >= end => return None,
1051 ops::Bound::Excluded(start) => start + 1,
1053
1054 ops::Bound::Included(start) if start > end => return None,
1055 ops::Bound::Included(start) => start,
1056
1057 ops::Bound::Unbounded => 0,
1058 };
1059
1060 Some(start..end)
1061}
1062
1063#[inline]
1066#[ferrocene::prevalidated]
1067pub(crate) const fn into_slice_range(
1068 len: usize,
1069 (start, end): (ops::Bound<usize>, ops::Bound<usize>),
1070) -> ops::Range<usize> {
1071 let end = match end {
1072 ops::Bound::Included(end) if end >= len => slice_index_fail(0, end, len),
1073 ops::Bound::Included(end) => end + 1,
1075
1076 ops::Bound::Excluded(end) if end > len => slice_index_fail(0, end, len),
1077 ops::Bound::Excluded(end) => end,
1078
1079 ops::Bound::Unbounded => len,
1080 };
1081
1082 let start = match start {
1083 ops::Bound::Excluded(start) if start >= end => slice_index_fail(start, end, len),
1084 ops::Bound::Excluded(start) => start + 1,
1086
1087 ops::Bound::Included(start) if start > end => slice_index_fail(start, end, len),
1088 ops::Bound::Included(start) => start,
1089
1090 ops::Bound::Unbounded => 0,
1091 };
1092
1093 start..end
1094}
1095
1096#[stable(feature = "slice_index_with_ops_bound_pair", since = "1.53.0")]
1097unsafe impl<T> SliceIndex<[T]> for (ops::Bound<usize>, ops::Bound<usize>) {
1098 type Output = [T];
1099
1100 #[inline]
1101 #[ferrocene::prevalidated]
1102 fn get(self, slice: &[T]) -> Option<&Self::Output> {
1103 try_into_slice_range(slice.len(), self)?.get(slice)
1104 }
1105
1106 #[inline]
1107 #[ferrocene::prevalidated]
1108 fn get_mut(self, slice: &mut [T]) -> Option<&mut Self::Output> {
1109 try_into_slice_range(slice.len(), self)?.get_mut(slice)
1110 }
1111
1112 #[inline]
1113 #[ferrocene::prevalidated]
1114 unsafe fn get_unchecked(self, slice: *const [T]) -> *const Self::Output {
1115 unsafe { into_range_unchecked(slice.len(), self).get_unchecked(slice) }
1117 }
1118
1119 #[inline]
1120 #[ferrocene::prevalidated]
1121 unsafe fn get_unchecked_mut(self, slice: *mut [T]) -> *mut Self::Output {
1122 unsafe { into_range_unchecked(slice.len(), self).get_unchecked_mut(slice) }
1124 }
1125
1126 #[inline]
1127 #[ferrocene::prevalidated]
1128 fn index(self, slice: &[T]) -> &Self::Output {
1129 into_slice_range(slice.len(), self).index(slice)
1130 }
1131
1132 #[inline]
1133 #[ferrocene::prevalidated]
1134 fn index_mut(self, slice: &mut [T]) -> &mut Self::Output {
1135 into_slice_range(slice.len(), self).index_mut(slice)
1136 }
1137}