Skip to content

Commit 0504415

Browse files
Rollup merge of rust-lang#143921 - oli-obk:const-index, r=fee1-dead
Constify `Index` traits tracking issue: rust-lang#143775 the `SliceIndex` trait cannot be implemented by users as it is sealed. While it would be useful for the `get` method on slices, it seems weird to have a feature gate for that that isn't also gating index syntax at the same time, so I put them under the same feature gate. r? ```@fee1-dead```
2 parents 4a3608a + 2b4ede7 commit 0504415

File tree

16 files changed

+146
-96
lines changed

16 files changed

+146
-96
lines changed

library/core/src/array/mod.rs

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -374,9 +374,10 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] {
374374
}
375375

376376
#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
377-
impl<T, I, const N: usize> Index<I> for [T; N]
377+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
378+
impl<T, I, const N: usize> const Index<I> for [T; N]
378379
where
379-
[T]: Index<I>,
380+
[T]: ~const Index<I>,
380381
{
381382
type Output = <[T] as Index<I>>::Output;
382383

@@ -387,9 +388,10 @@ where
387388
}
388389

389390
#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
390-
impl<T, I, const N: usize> IndexMut<I> for [T; N]
391+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
392+
impl<T, I, const N: usize> const IndexMut<I> for [T; N]
391393
where
392-
[T]: IndexMut<I>,
394+
[T]: ~const IndexMut<I>,
393395
{
394396
#[inline]
395397
fn index_mut(&mut self, index: I) -> &mut Self::Output {

library/core/src/ops/index.rs

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,6 +55,8 @@
5555
#[doc(alias = "]")]
5656
#[doc(alias = "[")]
5757
#[doc(alias = "[]")]
58+
#[const_trait]
59+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
5860
pub trait Index<Idx: ?Sized> {
5961
/// The returned type after indexing.
6062
#[stable(feature = "rust1", since = "1.0.0")]
@@ -165,7 +167,9 @@ see chapter in The Book <https://doc.rust-lang.org/book/ch08-02-strings.html#ind
165167
#[doc(alias = "[")]
166168
#[doc(alias = "]")]
167169
#[doc(alias = "[]")]
168-
pub trait IndexMut<Idx: ?Sized>: Index<Idx> {
170+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
171+
#[const_trait]
172+
pub trait IndexMut<Idx: ?Sized>: ~const Index<Idx> {
169173
/// Performs the mutable indexing (`container[index]`) operation.
170174
///
171175
/// # Panics

library/core/src/ptr/const_ptr.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1524,10 +1524,11 @@ impl<T> *const [T] {
15241524
/// }
15251525
/// ```
15261526
#[unstable(feature = "slice_ptr_get", issue = "74265")]
1527+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
15271528
#[inline]
1528-
pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
1529+
pub const unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
15291530
where
1530-
I: SliceIndex<[T]>,
1531+
I: ~const SliceIndex<[T]>,
15311532
{
15321533
// SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
15331534
unsafe { index.get_unchecked(self) }

library/core/src/ptr/mut_ptr.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1881,10 +1881,11 @@ impl<T> *mut [T] {
18811881
/// }
18821882
/// ```
18831883
#[unstable(feature = "slice_ptr_get", issue = "74265")]
1884+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
18841885
#[inline(always)]
1885-
pub unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
1886+
pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
18861887
where
1887-
I: SliceIndex<[T]>,
1888+
I: ~const SliceIndex<[T]>,
18881889
{
18891890
// SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
18901891
unsafe { index.get_unchecked_mut(self) }

library/core/src/ptr/non_null.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1597,10 +1597,11 @@ impl<T> NonNull<[T]> {
15971597
/// }
15981598
/// ```
15991599
#[unstable(feature = "slice_ptr_get", issue = "74265")]
1600+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
16001601
#[inline]
1601-
pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
1602+
pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
16021603
where
1603-
I: SliceIndex<[T]>,
1604+
I: ~const SliceIndex<[T]>,
16041605
{
16051606
// SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
16061607
// As a consequence, the resulting pointer cannot be null.

library/core/src/range.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -186,14 +186,17 @@ impl<T> IntoBounds<T> for Range<T> {
186186
}
187187

188188
#[unstable(feature = "new_range_api", issue = "125687")]
189-
impl<T> From<Range<T>> for legacy::Range<T> {
189+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
190+
impl<T> const From<Range<T>> for legacy::Range<T> {
190191
#[inline]
191192
fn from(value: Range<T>) -> Self {
192193
Self { start: value.start, end: value.end }
193194
}
194195
}
196+
195197
#[unstable(feature = "new_range_api", issue = "125687")]
196-
impl<T> From<legacy::Range<T>> for Range<T> {
198+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
199+
impl<T> const From<legacy::Range<T>> for Range<T> {
197200
#[inline]
198201
fn from(value: legacy::Range<T>) -> Self {
199202
Self { start: value.start, end: value.end }
@@ -362,7 +365,8 @@ impl<T> IntoBounds<T> for RangeInclusive<T> {
362365
}
363366

364367
#[unstable(feature = "new_range_api", issue = "125687")]
365-
impl<T> From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
368+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
369+
impl<T> const From<RangeInclusive<T>> for legacy::RangeInclusive<T> {
366370
#[inline]
367371
fn from(value: RangeInclusive<T>) -> Self {
368372
Self::new(value.start, value.end)
@@ -506,14 +510,16 @@ impl<T> IntoBounds<T> for RangeFrom<T> {
506510
}
507511

508512
#[unstable(feature = "new_range_api", issue = "125687")]
509-
impl<T> From<RangeFrom<T>> for legacy::RangeFrom<T> {
513+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
514+
impl<T> const From<RangeFrom<T>> for legacy::RangeFrom<T> {
510515
#[inline]
511516
fn from(value: RangeFrom<T>) -> Self {
512517
Self { start: value.start }
513518
}
514519
}
515520
#[unstable(feature = "new_range_api", issue = "125687")]
516-
impl<T> From<legacy::RangeFrom<T>> for RangeFrom<T> {
521+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
522+
impl<T> const From<legacy::RangeFrom<T>> for RangeFrom<T> {
517523
#[inline]
518524
fn from(value: legacy::RangeFrom<T>) -> Self {
519525
Self { start: value.start }

library/core/src/slice/index.rs

Lines changed: 30 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,10 @@ use crate::ub_checks::assert_unsafe_precondition;
66
use crate::{ops, range};
77

88
#[stable(feature = "rust1", since = "1.0.0")]
9-
impl<T, I> ops::Index<I> for [T]
9+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
10+
impl<T, I> const ops::Index<I> for [T]
1011
where
11-
I: SliceIndex<[T]>,
12+
I: ~const SliceIndex<[T]>,
1213
{
1314
type Output = I::Output;
1415

@@ -19,9 +20,10 @@ where
1920
}
2021

2122
#[stable(feature = "rust1", since = "1.0.0")]
22-
impl<T, I> ops::IndexMut<I> for [T]
23+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
24+
impl<T, I> const ops::IndexMut<I> for [T]
2325
where
24-
I: SliceIndex<[T]>,
26+
I: ~const SliceIndex<[T]>,
2527
{
2628
#[inline(always)]
2729
fn index_mut(&mut self, index: I) -> &mut I::Output {
@@ -158,6 +160,8 @@ mod private_slice_index {
158160
message = "the type `{T}` cannot be indexed by `{Self}`",
159161
label = "slice indices are of type `usize` or ranges of `usize`"
160162
)]
163+
#[const_trait]
164+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
161165
pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
162166
/// The output type returned by methods.
163167
#[stable(feature = "slice_get_slice", since = "1.28.0")]
@@ -208,7 +212,8 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
208212

209213
/// The methods `index` and `index_mut` panic if the index is out of bounds.
210214
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
211-
unsafe impl<T> SliceIndex<[T]> for usize {
215+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
216+
unsafe impl<T> const SliceIndex<[T]> for usize {
212217
type Output = T;
213218

214219
#[inline]
@@ -278,7 +283,8 @@ unsafe impl<T> SliceIndex<[T]> for usize {
278283

279284
/// Because `IndexRange` guarantees `start <= end`, fewer checks are needed here
280285
/// than there are for a general `Range<usize>` (which might be `100..3`).
281-
unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
286+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
287+
unsafe impl<T> const SliceIndex<[T]> for ops::IndexRange {
282288
type Output = [T];
283289

284290
#[inline]
@@ -354,7 +360,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::IndexRange {
354360
/// - the start of the range is greater than the end of the range or
355361
/// - the end of the range is out of bounds.
356362
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
357-
unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
363+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
364+
unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
358365
type Output = [T];
359366

360367
#[inline]
@@ -453,7 +460,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
453460
}
454461

455462
#[unstable(feature = "new_range_api", issue = "125687")]
456-
unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
463+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
464+
unsafe impl<T> const SliceIndex<[T]> for range::Range<usize> {
457465
type Output = [T];
458466

459467
#[inline]
@@ -491,7 +499,8 @@ unsafe impl<T> SliceIndex<[T]> for range::Range<usize> {
491499

492500
/// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
493501
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
494-
unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
502+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
503+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
495504
type Output = [T];
496505

497506
#[inline]
@@ -529,7 +538,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
529538

530539
/// The methods `index` and `index_mut` panic if the start of the range is out of bounds.
531540
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
532-
unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
541+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
542+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
533543
type Output = [T];
534544

535545
#[inline]
@@ -574,7 +584,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
574584
}
575585

576586
#[unstable(feature = "new_range_api", issue = "125687")]
577-
unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
587+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
588+
unsafe impl<T> const SliceIndex<[T]> for range::RangeFrom<usize> {
578589
type Output = [T];
579590

580591
#[inline]
@@ -611,7 +622,8 @@ unsafe impl<T> SliceIndex<[T]> for range::RangeFrom<usize> {
611622
}
612623

613624
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
614-
unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
625+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
626+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
615627
type Output = [T];
616628

617629
#[inline]
@@ -650,7 +662,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
650662
/// - the start of the range is greater than the end of the range or
651663
/// - the end of the range is out of bounds.
652664
#[stable(feature = "inclusive_range", since = "1.26.0")]
653-
unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
665+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
666+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
654667
type Output = [T];
655668

656669
#[inline]
@@ -693,7 +706,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
693706
}
694707

695708
#[unstable(feature = "new_range_api", issue = "125687")]
696-
unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
709+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
710+
unsafe impl<T> const SliceIndex<[T]> for range::RangeInclusive<usize> {
697711
type Output = [T];
698712

699713
#[inline]
@@ -731,7 +745,8 @@ unsafe impl<T> SliceIndex<[T]> for range::RangeInclusive<usize> {
731745

732746
/// The methods `index` and `index_mut` panic if the end of the range is out of bounds.
733747
#[stable(feature = "inclusive_range", since = "1.26.0")]
734-
unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
748+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
749+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
735750
type Output = [T];
736751

737752
#[inline]

library/core/src/slice/mod.rs

Lines changed: 12 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -568,9 +568,10 @@ impl<T> [T] {
568568
#[rustc_no_implicit_autorefs]
569569
#[inline]
570570
#[must_use]
571-
pub fn get<I>(&self, index: I) -> Option<&I::Output>
571+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
572+
pub const fn get<I>(&self, index: I) -> Option<&I::Output>
572573
where
573-
I: SliceIndex<Self>,
574+
I: ~const SliceIndex<Self>,
574575
{
575576
index.get(self)
576577
}
@@ -594,9 +595,10 @@ impl<T> [T] {
594595
#[rustc_no_implicit_autorefs]
595596
#[inline]
596597
#[must_use]
597-
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
598+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
599+
pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
598600
where
599-
I: SliceIndex<Self>,
601+
I: ~const SliceIndex<Self>,
600602
{
601603
index.get_mut(self)
602604
}
@@ -633,9 +635,10 @@ impl<T> [T] {
633635
#[inline]
634636
#[must_use]
635637
#[track_caller]
636-
pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
638+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
639+
pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
637640
where
638-
I: SliceIndex<Self>,
641+
I: ~const SliceIndex<Self>,
639642
{
640643
// SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;
641644
// the slice is dereferenceable because `self` is a safe reference.
@@ -677,9 +680,10 @@ impl<T> [T] {
677680
#[inline]
678681
#[must_use]
679682
#[track_caller]
680-
pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
683+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
684+
pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
681685
where
682-
I: SliceIndex<Self>,
686+
I: ~const SliceIndex<Self>,
683687
{
684688
// SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;
685689
// the slice is dereferenceable because `self` is a safe reference.

library/core/src/str/mod.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -589,8 +589,9 @@ impl str {
589589
/// assert!(v.get(..42).is_none());
590590
/// ```
591591
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
592+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
592593
#[inline]
593-
pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
594+
pub const fn get<I: ~const SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
594595
i.get(self)
595596
}
596597

@@ -621,8 +622,9 @@ impl str {
621622
/// assert_eq!("HEllo", v);
622623
/// ```
623624
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
625+
#[rustc_const_unstable(feature = "const_index", issue = "143775")]
624626
#[inline]
625-
pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
627+
pub const fn get_mut<I: ~const SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
626628
i.get_mut(self)
627629
}
628630

0 commit comments

Comments
 (0)