Skip to content

Commit 4654a91

Browse files
committed
Constify slice index for strings
1 parent 5941fef commit 4654a91

File tree

12 files changed

+104
-59
lines changed

12 files changed

+104
-59
lines changed

library/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 {

library/core/src/lib.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -148,7 +148,8 @@
148148
#![feature(variant_count)]
149149
#![feature(const_array_from_ref)]
150150
#![feature(const_slice_from_ref)]
151-
#![feature(const_slice_index_impls)]
151+
#![feature(const_slice_index)]
152+
#![feature(const_is_char_boundary)]
152153
//
153154
// Language features:
154155
#![feature(abi_unadjusted)]

library/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
}

library/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) }

library/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) }

library/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.

library/core/src/slice/index.rs

+17-14
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ use crate::ops;
55
use crate::ptr;
66

77
#[stable(feature = "rust1", since = "1.0.0")]
8-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
8+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
99
impl<T, I> const ops::Index<I> for [T]
1010
where
1111
I: ~const SliceIndex<[T]>,
@@ -19,7 +19,7 @@ where
1919
}
2020

2121
#[stable(feature = "rust1", since = "1.0.0")]
22-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
22+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
2323
impl<T, I> const ops::IndexMut<I> for [T]
2424
where
2525
I: ~const SliceIndex<[T]>,
@@ -30,16 +30,19 @@ where
3030
}
3131
}
3232

33-
3433
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
3534
#[cfg_attr(feature = "panic_immediate_abort", inline)]
3635
#[cold]
3736
#[track_caller]
38-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
37+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
3938
const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
4039
// SAFETY: we are just panicking here
4140
unsafe {
42-
const_eval_select((index, len), slice_start_index_len_fail_ct, slice_start_index_len_fail_rt)
41+
const_eval_select(
42+
(index, len),
43+
slice_start_index_len_fail_ct,
44+
slice_start_index_len_fail_rt,
45+
)
4346
}
4447
}
4548

@@ -56,7 +59,7 @@ const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! {
5659
#[cfg_attr(feature = "panic_immediate_abort", inline)]
5760
#[cold]
5861
#[track_caller]
59-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
62+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
6063
const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
6164
// SAFETY: we are just panicking here
6265
unsafe {
@@ -77,7 +80,7 @@ const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! {
7780
#[cfg_attr(feature = "panic_immediate_abort", inline)]
7881
#[cold]
7982
#[track_caller]
80-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
83+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
8184
const fn slice_index_order_fail(index: usize, end: usize) -> ! {
8285
// SAFETY: we are just panicking here
8386
unsafe { const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) }
@@ -194,7 +197,7 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
194197
}
195198

196199
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
197-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
200+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
198201
unsafe impl<T> const SliceIndex<[T]> for usize {
199202
type Output = T;
200203

@@ -239,7 +242,7 @@ unsafe impl<T> const SliceIndex<[T]> for usize {
239242
}
240243

241244
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
242-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
245+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
243246
unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
244247
type Output = [T];
245248

@@ -304,7 +307,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
304307
}
305308

306309
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
307-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
310+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
308311
unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
309312
type Output = [T];
310313

@@ -342,7 +345,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
342345
}
343346

344347
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
345-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
348+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
346349
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
347350
type Output = [T];
348351

@@ -388,7 +391,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
388391
}
389392

390393
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
391-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
394+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
392395
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
393396
type Output = [T];
394397

@@ -424,7 +427,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
424427
}
425428

426429
#[stable(feature = "inclusive_range", since = "1.26.0")]
427-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
430+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
428431
unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
429432
type Output = [T];
430433

@@ -468,7 +471,7 @@ unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
468471
}
469472

470473
#[stable(feature = "inclusive_range", since = "1.26.0")]
471-
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
474+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
472475
unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
473476
type Output = [T];
474477

library/core/src/slice/mod.rs

+12-8
Original file line numberDiff line numberDiff line change
@@ -321,10 +321,11 @@ impl<T> [T] {
321321
/// assert_eq!(None, v.get(0..4));
322322
/// ```
323323
#[stable(feature = "rust1", since = "1.0.0")]
324+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
324325
#[inline]
325-
pub fn get<I>(&self, index: I) -> Option<&I::Output>
326+
pub const fn get<I>(&self, index: I) -> Option<&I::Output>
326327
where
327-
I: SliceIndex<Self>,
328+
I: ~const SliceIndex<Self>,
328329
{
329330
index.get(self)
330331
}
@@ -345,10 +346,11 @@ impl<T> [T] {
345346
/// assert_eq!(x, &[0, 42, 2]);
346347
/// ```
347348
#[stable(feature = "rust1", since = "1.0.0")]
349+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
348350
#[inline]
349-
pub fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
351+
pub const fn get_mut<I>(&mut self, index: I) -> Option<&mut I::Output>
350352
where
351-
I: SliceIndex<Self>,
353+
I: ~const SliceIndex<Self>,
352354
{
353355
index.get_mut(self)
354356
}
@@ -376,10 +378,11 @@ impl<T> [T] {
376378
/// }
377379
/// ```
378380
#[stable(feature = "rust1", since = "1.0.0")]
381+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
379382
#[inline]
380-
pub unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
383+
pub const unsafe fn get_unchecked<I>(&self, index: I) -> &I::Output
381384
where
382-
I: SliceIndex<Self>,
385+
I: ~const SliceIndex<Self>,
383386
{
384387
// SAFETY: the caller must uphold most of the safety requirements for `get_unchecked`;
385388
// the slice is dereferenceable because `self` is a safe reference.
@@ -412,10 +415,11 @@ impl<T> [T] {
412415
/// assert_eq!(x, &[1, 13, 4]);
413416
/// ```
414417
#[stable(feature = "rust1", since = "1.0.0")]
418+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
415419
#[inline]
416-
pub unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
420+
pub const unsafe fn get_unchecked_mut<I>(&mut self, index: I) -> &mut I::Output
417421
where
418-
I: SliceIndex<Self>,
422+
I: ~const SliceIndex<Self>,
419423
{
420424
// SAFETY: the caller must uphold the safety requirements for `get_unchecked_mut`;
421425
// the slice is dereferenceable because `self` is a safe reference.

library/core/src/str/mod.rs

+30-6
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,23 @@ use iter::{MatchesInternal, SplitNInternal};
7979
#[inline(never)]
8080
#[cold]
8181
#[track_caller]
82-
fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
82+
#[rustc_allow_const_fn_unstable(const_eval_select)]
83+
const fn slice_error_fail(s: &str, begin: usize, end: usize) -> ! {
84+
// SAFETY: panics for both branches
85+
unsafe {
86+
crate::intrinsics::const_eval_select(
87+
(s, begin, end),
88+
slice_error_fail_ct,
89+
slice_error_fail_rt,
90+
)
91+
}
92+
}
93+
94+
const fn slice_error_fail_ct(_: &str, _: usize, _: usize) -> ! {
95+
panic!("failed to slice string");
96+
}
97+
98+
fn slice_error_fail_rt(s: &str, begin: usize, end: usize) -> ! {
8399
const MAX_DISPLAY_LENGTH: usize = 256;
84100
let trunc_len = s.floor_char_boundary(MAX_DISPLAY_LENGTH);
85101
let s_trunc = &s[..trunc_len];
@@ -189,8 +205,9 @@ impl str {
189205
/// ```
190206
#[must_use]
191207
#[stable(feature = "is_char_boundary", since = "1.9.0")]
208+
#[rustc_const_unstable(feature = "const_is_char_boundary", issue = "none")]
192209
#[inline]
193-
pub fn is_char_boundary(&self, index: usize) -> bool {
210+
pub const fn is_char_boundary(&self, index: usize) -> bool {
194211
// 0 is always ok.
195212
// Test for 0 explicitly so that it can optimize out the check
196213
// easily and skip reading string data for that case.
@@ -418,8 +435,9 @@ impl str {
418435
/// assert!(v.get(..42).is_none());
419436
/// ```
420437
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
438+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
421439
#[inline]
422-
pub fn get<I: SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
440+
pub const fn get<I: ~const SliceIndex<str>>(&self, i: I) -> Option<&I::Output> {
423441
i.get(self)
424442
}
425443

@@ -450,8 +468,9 @@ impl str {
450468
/// assert_eq!("HEllo", v);
451469
/// ```
452470
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
471+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
453472
#[inline]
454-
pub fn get_mut<I: SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
473+
pub const fn get_mut<I: ~const SliceIndex<str>>(&mut self, i: I) -> Option<&mut I::Output> {
455474
i.get_mut(self)
456475
}
457476

@@ -482,8 +501,9 @@ impl str {
482501
/// }
483502
/// ```
484503
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
504+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
485505
#[inline]
486-
pub unsafe fn get_unchecked<I: SliceIndex<str>>(&self, i: I) -> &I::Output {
506+
pub const unsafe fn get_unchecked<I: ~const SliceIndex<str>>(&self, i: I) -> &I::Output {
487507
// SAFETY: the caller must uphold the safety contract for `get_unchecked`;
488508
// the slice is dereferenceable because `self` is a safe reference.
489509
// The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.
@@ -517,8 +537,12 @@ impl str {
517537
/// }
518538
/// ```
519539
#[stable(feature = "str_checked_slicing", since = "1.20.0")]
540+
#[rustc_const_unstable(feature = "const_slice_index", issue = "none")]
520541
#[inline]
521-
pub unsafe fn get_unchecked_mut<I: SliceIndex<str>>(&mut self, i: I) -> &mut I::Output {
542+
pub const unsafe fn get_unchecked_mut<I: ~const SliceIndex<str>>(
543+
&mut self,
544+
i: I,
545+
) -> &mut I::Output {
522546
// SAFETY: the caller must uphold the safety contract for `get_unchecked_mut`;
523547
// the slice is dereferenceable because `self` is a safe reference.
524548
// The returned pointer is safe because impls of `SliceIndex` have to guarantee that it is.

0 commit comments

Comments
 (0)