Skip to content

Commit 5941fef

Browse files
committed
Constify slice indexing
1 parent 03a8cc7 commit 5941fef

File tree

3 files changed

+66
-17
lines changed

3 files changed

+66
-17
lines changed

library/core/src/lib.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,7 @@
148148
#![feature(variant_count)]
149149
#![feature(const_array_from_ref)]
150150
#![feature(const_slice_from_ref)]
151+
#![feature(const_slice_index_impls)]
151152
//
152153
// Language features:
153154
#![feature(abi_unadjusted)]

library/core/src/ops/range.rs

Lines changed: 1 addition & 1 deletion
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.

library/core/src/slice/index.rs

Lines changed: 64 additions & 16 deletions
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_impls", 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,53 +19,92 @@ 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_impls", 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 {
2629
index.index_mut(self)
2730
}
2831
}
2932

33+
3034
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
3135
#[cfg_attr(feature = "panic_immediate_abort", inline)]
3236
#[cold]
3337
#[track_caller]
34-
fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
38+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
39+
const fn slice_start_index_len_fail(index: usize, len: usize) -> ! {
40+
// SAFETY: we are just panicking here
41+
unsafe {
42+
const_eval_select((index, len), slice_start_index_len_fail_ct, slice_start_index_len_fail_rt)
43+
}
44+
}
45+
46+
// FIXME const-hack
47+
fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! {
3548
panic!("range start index {} out of range for slice of length {}", index, len);
3649
}
3750

51+
const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! {
52+
panic!("slice start index is out of range for slice");
53+
}
54+
3855
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
3956
#[cfg_attr(feature = "panic_immediate_abort", inline)]
4057
#[cold]
4158
#[track_caller]
42-
fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
59+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
60+
const fn slice_end_index_len_fail(index: usize, len: usize) -> ! {
61+
// SAFETY: we are just panicking here
62+
unsafe {
63+
const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt)
64+
}
65+
}
66+
67+
// FIXME const-hack
68+
fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! {
4369
panic!("range end index {} out of range for slice of length {}", index, len);
4470
}
4571

72+
const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! {
73+
panic!("slice end index is out of range for slice");
74+
}
75+
4676
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
4777
#[cfg_attr(feature = "panic_immediate_abort", inline)]
4878
#[cold]
4979
#[track_caller]
50-
fn slice_index_order_fail(index: usize, end: usize) -> ! {
80+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
81+
const fn slice_index_order_fail(index: usize, end: usize) -> ! {
82+
// SAFETY: we are just panicking here
83+
unsafe { const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) }
84+
}
85+
86+
// FIXME const-hack
87+
fn slice_index_order_fail_rt(index: usize, end: usize) -> ! {
5188
panic!("slice index starts at {} but ends at {}", index, end);
5289
}
5390

91+
const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! {
92+
panic!("slice index start is larger than end");
93+
}
94+
5495
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
5596
#[cfg_attr(feature = "panic_immediate_abort", inline)]
5697
#[cold]
5798
#[track_caller]
58-
fn slice_start_index_overflow_fail() -> ! {
99+
const fn slice_start_index_overflow_fail() -> ! {
59100
panic!("attempted to index slice from after maximum usize");
60101
}
61102

62103
#[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))]
63104
#[cfg_attr(feature = "panic_immediate_abort", inline)]
64105
#[cold]
65106
#[track_caller]
66-
fn slice_end_index_overflow_fail() -> ! {
107+
const fn slice_end_index_overflow_fail() -> ! {
67108
panic!("attempted to index slice up to maximum usize");
68109
}
69110

@@ -153,7 +194,8 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed {
153194
}
154195

155196
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
156-
unsafe impl<T> SliceIndex<[T]> for usize {
197+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
198+
unsafe impl<T> const SliceIndex<[T]> for usize {
157199
type Output = T;
158200

159201
#[inline]
@@ -197,7 +239,8 @@ unsafe impl<T> SliceIndex<[T]> for usize {
197239
}
198240

199241
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
200-
unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
242+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
243+
unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> {
201244
type Output = [T];
202245

203246
#[inline]
@@ -261,7 +304,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> {
261304
}
262305

263306
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
264-
unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
307+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
308+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> {
265309
type Output = [T];
266310

267311
#[inline]
@@ -298,7 +342,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> {
298342
}
299343

300344
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
301-
unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
345+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
346+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> {
302347
type Output = [T];
303348

304349
#[inline]
@@ -343,7 +388,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> {
343388
}
344389

345390
#[stable(feature = "slice_get_slice_impls", since = "1.15.0")]
346-
unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
391+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
392+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull {
347393
type Output = [T];
348394

349395
#[inline]
@@ -378,7 +424,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFull {
378424
}
379425

380426
#[stable(feature = "inclusive_range", since = "1.26.0")]
381-
unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
427+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
428+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> {
382429
type Output = [T];
383430

384431
#[inline]
@@ -421,7 +468,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> {
421468
}
422469

423470
#[stable(feature = "inclusive_range", since = "1.26.0")]
424-
unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> {
471+
#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")]
472+
unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> {
425473
type Output = [T];
426474

427475
#[inline]

0 commit comments

Comments
 (0)