Skip to content

Commit 0215813

Browse files
authored
Rollup merge of rust-lang#94657 - fee1-dead:const_slice_index, r=oli-obk
Constify `Index{,Mut}` for `[T]`, `str`, and `[T; N]` Several panic functions were rewired (via `const_eval_select`) to simpler implementations that do not require formatting for compile-time usage. r? ```@oli-obk```
2 parents 58b9bca + 0645e93 commit 0215813

File tree

11 files changed

+147
-53
lines changed

11 files changed

+147
-53
lines changed

core/src/array/mod.rs

+6-4
Original file line numberDiff line numberDiff line change
@@ -276,9 +276,10 @@ impl<'a, T, const N: usize> IntoIterator for &'a mut [T; N] {
276276
}
277277

278278
#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
279-
impl<T, I, const N: usize> Index<I> for [T; N]
279+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
280+
impl<T, I, const N: usize> const Index<I> for [T; N]
280281
where
281-
[T]: Index<I>,
282+
[T]: ~const Index<I>,
282283
{
283284
type Output = <[T] as Index<I>>::Output;
284285

@@ -289,9 +290,10 @@ where
289290
}
290291

291292
#[stable(feature = "index_trait_on_arrays", since = "1.50.0")]
292-
impl<T, I, const N: usize> IndexMut<I> for [T; N]
293+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
294+
impl<T, I, const N: usize> const IndexMut<I> for [T; N]
293295
where
294-
[T]: IndexMut<I>,
296+
[T]: ~const IndexMut<I>,
295297
{
296298
#[inline]
297299
fn index_mut(&mut self, index: I) -> &mut Self::Output {

core/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -149,6 +149,8 @@
149149
#![feature(variant_count)]
150150
#![feature(const_array_from_ref)]
151151
#![feature(const_slice_from_ref)]
152+
#![feature(const_slice_index)]
153+
#![feature(const_is_char_boundary)]
152154
//
153155
// Language features:
154156
#![feature(abi_unadjusted)]

core/src/num/mod.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -809,7 +809,7 @@ impl u8 {
809809
ascii::escape_default(self)
810810
}
811811

812-
pub(crate) fn is_utf8_char_boundary(self) -> bool {
812+
pub(crate) const fn is_utf8_char_boundary(self) -> bool {
813813
// This is bit magic equivalent to: b < 128 || b >= 192
814814
(self as i8) >= -0x40
815815
}

core/src/ops/range.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -446,7 +446,7 @@ impl RangeInclusive<usize> {
446446
/// Converts to an exclusive `Range` for `SliceIndex` implementations.
447447
/// The caller is responsible for dealing with `end == usize::MAX`.
448448
#[inline]
449-
pub(crate) fn into_slice_range(self) -> Range<usize> {
449+
pub(crate) const fn into_slice_range(self) -> Range<usize> {
450450
// If we're not exhausted, we want to simply slice `start..end + 1`.
451451
// If we are exhausted, then slicing with `end + 1..end + 1` gives us an
452452
// empty range that is still subject to bounds-checks for that endpoint.

core/src/ptr/const_ptr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1032,10 +1032,11 @@ impl<T> *const [T] {
10321032
/// }
10331033
/// ```
10341034
#[unstable(feature = "slice_ptr_get", issue = "74265")]
1035+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
10351036
#[inline]
1036-
pub unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
1037+
pub const unsafe fn get_unchecked<I>(self, index: I) -> *const I::Output
10371038
where
1038-
I: SliceIndex<[T]>,
1039+
I: ~const SliceIndex<[T]>,
10391040
{
10401041
// SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
10411042
unsafe { index.get_unchecked(self) }

core/src/ptr/mut_ptr.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -1302,10 +1302,11 @@ impl<T> *mut [T] {
13021302
/// }
13031303
/// ```
13041304
#[unstable(feature = "slice_ptr_get", issue = "74265")]
1305+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
13051306
#[inline(always)]
1306-
pub unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
1307+
pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> *mut I::Output
13071308
where
1308-
I: SliceIndex<[T]>,
1309+
I: ~const SliceIndex<[T]>,
13091310
{
13101311
// SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
13111312
unsafe { index.get_unchecked_mut(self) }

core/src/ptr/non_null.rs

+3-2
Original file line numberDiff line numberDiff line change
@@ -630,10 +630,11 @@ impl<T> NonNull<[T]> {
630630
/// }
631631
/// ```
632632
#[unstable(feature = "slice_ptr_get", issue = "74265")]
633+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
633634
#[inline]
634-
pub unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
635+
pub const unsafe fn get_unchecked_mut<I>(self, index: I) -> NonNull<I::Output>
635636
where
636-
I: SliceIndex<[T]>,
637+
I: ~const SliceIndex<[T]>,
637638
{
638639
// SAFETY: the caller ensures that `self` is dereferenceable and `index` in-bounds.
639640
// As a consequence, the resulting pointer cannot be null.

core/src/slice/index.rs

+67-16
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,14 @@
11
//! Indexing implementations for `[T]`.
22
3+
use crate::intrinsics::const_eval_select;
34
use crate::ops;
45
use crate::ptr;
56

67
#[stable(feature = "rust1", since = "1.0.0")]
7-
impl<T, I> ops::Index<I> for [T]
8+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
9+
impl<T, I> const ops::Index<I> for [T]
810
where
9-
I: SliceIndex<[T]>,
11+
I: ~const SliceIndex<[T]>,
1012
{
1113
type Output = I::Output;
1214

@@ -17,9 +19,10 @@ where
1719
}
1820

1921
#[stable(feature = "rust1", since = "1.0.0")]
20-
impl<T, I> ops::IndexMut<I> for [T]
22+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
23+
impl<T, I> const ops::IndexMut<I> for [T]
2124
where
22-
I: SliceIndex<[T]>,
25+
I: ~const SliceIndex<[T]>,
2326
{
2427
#[inline]
2528
fn index_mut(&mut self, index: I) -> &mut I::Output {
@@ -31,39 +34,80 @@ where
3134
#[cfg_attr(feature = "panic_immediate_abort", inline)]
3235
#[cold]
3336
#[track_caller]
34-
fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
37+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
38+
const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
39+
// SAFETY: we are just panicking here
40+
unsafe {
41+
const_eval_select(
42+
(index, len),
43+
slice_start_index_len_fail_ct,
44+
slice_start_index_len_fail_rt,
45+
)
46+
}
47+
}
48+
49+
// FIXME const-hack
50+
fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! {
3551
panic!("range start index {} out of range for slice of length {}", index, len);
3652
}
3753

54+
const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! {
55+
panic!("slice start index is out of range for slice");
56+
}
57+
3858
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
3959
#[cfg_attr(feature = "panic_immediate_abort", inline)]
4060
#[cold]
4161
#[track_caller]
42-
fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
62+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
63+
const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
64+
// SAFETY: we are just panicking here
65+
unsafe {
66+
const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt)
67+
}
68+
}
69+
70+
// FIXME const-hack
71+
fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! {
4372
panic!("range end index {} out of range for slice of length {}", index, len);
4473
}
4574

75+
const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! {
76+
panic!("slice end index is out of range for slice");
77+
}
78+
4679
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
4780
#[cfg_attr(feature = "panic_immediate_abort", inline)]
4881
#[cold]
4982
#[track_caller]
50-
fn slice_index_order_fail(index: usize, end: usize) -> ! {
83+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
84+
const fn slice_index_order_fail(index: usize, end: usize) -> ! {
85+
// SAFETY: we are just panicking here
86+
unsafe { const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) }
87+
}
88+
89+
// FIXME const-hack
90+
fn slice_index_order_fail_rt(index: usize, end: usize) -> ! {
5191
panic!("slice index starts at {} but ends at {}", index, end);
5292
}
5393

94+
const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! {
95+
panic!("slice index start is larger than end");
96+
}
97+
5498
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
5599
#[cfg_attr(feature = "panic_immediate_abort", inline)]
56100
#[cold]
57101
#[track_caller]
58-
fn slice_start_index_overflow_fail() -> ! {
102+
const fn slice_start_index_overflow_fail() -> ! {
59103
panic!("attempted to index slice from after maximum usize");
60104
}
61105

62106
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
63107
#[cfg_attr(feature = "panic_immediate_abort", inline)]
64108
#[cold]
65109
#[track_caller]
66-
fn slice_end_index_overflow_fail() -> ! {
110+
const fn slice_end_index_overflow_fail() -> ! {
67111
panic!("attempted to index slice up to maximum usize");
68112
}
69113

@@ -153,7 +197,8 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
153197
}
154198

155199
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
156-
unsafe impl<T> SliceIndex<[T]> for usize {
200+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
201+
unsafe impl<T> const SliceIndex<[T]> for usize {
157202
type Output = T;
158203

159204
#[inline]
@@ -197,7 +242,8 @@ unsafe impl<T> SliceIndex<[T]> for usize {
197242
}
198243

199244
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
200-
unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
245+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
246+
unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
201247
type Output = [T];
202248

203249
#[inline]
@@ -261,7 +307,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
261307
}
262308

263309
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
264-
unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
310+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
311+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
265312
type Output = [T];
266313

267314
#[inline]
@@ -298,7 +345,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
298345
}
299346

300347
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
301-
unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
348+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
349+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
302350
type Output = [T];
303351

304352
#[inline]
@@ -343,7 +391,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
343391
}
344392

345393
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
346-
unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
394+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
395+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
347396
type Output = [T];
348397

349398
#[inline]
@@ -378,7 +427,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
378427
}
379428

380429
#[stable(feature = "inclusive_range", since = "1.26.0")]
381-
unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
430+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
431+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
382432
type Output = [T];
383433

384434
#[inline]
@@ -421,7 +471,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
421471
}
422472

423473
#[stable(feature = "inclusive_range", since = "1.26.0")]
424-
unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
474+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
475+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
425476
type Output = [T];
426477

427478
#[inline]

core/src/slice/mod.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -324,10 +324,11 @@ impl<T> [T] {
324324
/// assert_eq!(None, v.get(0..4));
325325
/// ```
326326
#[stable(feature = "rust1", since = "1.0.0")]
327+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
327328
#[inline]
328-
pub fn get<I>(&self, index: I) -> Option<&I::Output>
329+
pub const fn get<I>(&self, index: I) -> Option<&I::Output>
329330
where
330-
I: SliceIndex<Self>,
331+
I: ~const SliceIndex<Self>,
331332
{
332333
index.get(self)
333334
}
@@ -348,10 +349,11 @@ impl<T> [T] {
348349
/// assert_eq!(x, &[0, 42, 2]);
349350
/// ```
350351
#[stable(feature = "rust1", since = "1.0.0")]
352+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
351353
#[inline]
352-
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
354+
pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
353355
where
354-
I: SliceIndex<Self>,
356+
I: ~const SliceIndex<Self>,
355357
{
356358
index.get_mut(self)
357359
}
@@ -379,10 +381,11 @@ impl<T> [T] {
379381
/// }
380382
/// ```
381383
#[stable(feature = "rust1", since = "1.0.0")]
384+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
382385
#[inline]
383-
pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
386+
pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
384387
where
385-
I: SliceIndex<Self>,
388+
I: ~const SliceIndex<Self>,
386389
{
387390
// SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;
388391
// the slice is dereferenceable because `self` is a safe reference.
@@ -415,10 +418,11 @@ impl<T> [T] {
415418
/// assert_eq!(x, &[1, 13, 4]);
416419
/// ```
417420
#[stable(feature = "rust1", since = "1.0.0")]
421+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
418422
#[inline]
419-
pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
423+
pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
420424
where
421-
I: SliceIndex<Self>,
425+
I: ~const SliceIndex<Self>,
422426
{
423427
// SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;
424428
// the slice is dereferenceable because `self` is a safe reference.

0 commit comments

Comments
 (0)