diff options
| author | Deadbeef <ent3rm4n@gmail.com> | 2022-02-22 12:39:36 +1100 |
|---|---|---|
| committer | Deadbeef <ent3rm4n@gmail.com> | 2022-02-22 12:39:36 +1100 |
| commit | 5941fef2920a631b22e870627c67a2cd9c30dafe (patch) | |
| tree | df57813ffacba5555eb44c27d4dd9e81afe1486b | |
| parent | 03a8cc7df1d65554a4d40825b0490c93ac0f0236 (diff) | |
| download | rust-5941fef2920a631b22e870627c67a2cd9c30dafe.tar.gz rust-5941fef2920a631b22e870627c67a2cd9c30dafe.zip | |
Constify slice indexing
| -rw-r--r-- | library/core/src/lib.rs | 1 | ||||
| -rw-r--r-- | library/core/src/ops/range.rs | 2 | ||||
| -rw-r--r-- | library/core/src/slice/index.rs | 80 |
3 files changed, 66 insertions, 17 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs index aa1ad9362a9..bad3fb0765c 100644 --- a/library/core/src/lib.rs +++ b/library/core/src/lib.rs @@ -148,6 +148,7 @@ #![feature(variant_count)] #![feature(const_array_from_ref)] #![feature(const_slice_from_ref)] +#![feature(const_slice_index_impls)] // // Language features: #![feature(abi_unadjusted)] diff --git a/library/core/src/ops/range.rs b/library/core/src/ops/range.rs index 11367220678..5029e0560b8 100644 --- a/library/core/src/ops/range.rs +++ b/library/core/src/ops/range.rs @@ -446,7 +446,7 @@ impl RangeInclusive<usize> { /// Converts to an exclusive `Range` for `SliceIndex` implementations. /// The caller is responsible for dealing with `end == usize::MAX`. #[inline] - pub(crate) fn into_slice_range(self) -> Range<usize> { + pub(crate) const fn into_slice_range(self) -> Range<usize> { // If we're not exhausted, we want to simply slice `start..end + 1`. // If we are exhausted, then slicing with `end + 1..end + 1` gives us an // empty range that is still subject to bounds-checks for that endpoint. diff --git a/library/core/src/slice/index.rs b/library/core/src/slice/index.rs index 0298bba8d32..3931c123352 100644 --- a/library/core/src/slice/index.rs +++ b/library/core/src/slice/index.rs @@ -1,12 +1,14 @@ //! Indexing implementations for `[T]`. +use crate::intrinsics::const_eval_select; use crate::ops; use crate::ptr; #[stable(feature = "rust1", since = "1.0.0")] -impl<T, I> ops::Index<I> for [T] +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +impl<T, I> const ops::Index<I> for [T] where - I: SliceIndex<[T]>, + I: ~const SliceIndex<[T]>, { type Output = I::Output; @@ -17,9 +19,10 @@ where } #[stable(feature = "rust1", since = "1.0.0")] -impl<T, I> ops::IndexMut<I> for [T] +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +impl<T, I> const ops::IndexMut<I> for [T] where - I: SliceIndex<[T]>, + I: ~const SliceIndex<[T]>, { #[inline] fn index_mut(&mut self, index: I) -> &mut I::Output { @@ -27,35 +30,73 @@ where } } + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_start_index_len_fail(index: usize, len: usize) -> ! { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +const fn slice_start_index_len_fail(index: usize, len: usize) -> ! { + // SAFETY: we are just panicking here + unsafe { + const_eval_select((index, len), slice_start_index_len_fail_ct, slice_start_index_len_fail_rt) + } +} + +// FIXME const-hack +fn slice_start_index_len_fail_rt(index: usize, len: usize) -> ! { panic!("range start index {} out of range for slice of length {}", index, len); } +const fn slice_start_index_len_fail_ct(_: usize, _: usize) -> ! { + panic!("slice start index is out of range for slice"); +} + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_end_index_len_fail(index: usize, len: usize) -> ! { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +const fn slice_end_index_len_fail(index: usize, len: usize) -> ! { + // SAFETY: we are just panicking here + unsafe { + const_eval_select((index, len), slice_end_index_len_fail_ct, slice_end_index_len_fail_rt) + } +} + +// FIXME const-hack +fn slice_end_index_len_fail_rt(index: usize, len: usize) -> ! { panic!("range end index {} out of range for slice of length {}", index, len); } +const fn slice_end_index_len_fail_ct(_: usize, _: usize) -> ! { + panic!("slice end index is out of range for slice"); +} + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_index_order_fail(index: usize, end: usize) -> ! { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +const fn slice_index_order_fail(index: usize, end: usize) -> ! { + // SAFETY: we are just panicking here + unsafe { const_eval_select((index, end), slice_index_order_fail_ct, slice_index_order_fail_rt) } +} + +// FIXME const-hack +fn slice_index_order_fail_rt(index: usize, end: usize) -> ! { panic!("slice index starts at {} but ends at {}", index, end); } +const fn slice_index_order_fail_ct(_: usize, _: usize) -> ! { + panic!("slice index start is larger than end"); +} + #[cfg_attr(not(feature = "panic_immediate_abort"), inline(never))] #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_start_index_overflow_fail() -> ! { +const fn slice_start_index_overflow_fail() -> ! { panic!("attempted to index slice from after maximum usize"); } @@ -63,7 +104,7 @@ fn slice_start_index_overflow_fail() -> ! { #[cfg_attr(feature = "panic_immediate_abort", inline)] #[cold] #[track_caller] -fn slice_end_index_overflow_fail() -> ! { +const fn slice_end_index_overflow_fail() -> ! { panic!("attempted to index slice up to maximum usize"); } @@ -153,7 +194,8 @@ pub unsafe trait SliceIndex<T: ?Sized>: private_slice_index::Sealed { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl<T> SliceIndex<[T]> for usize { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +unsafe impl<T> const SliceIndex<[T]> for usize { type Output = T; #[inline] @@ -197,7 +239,8 @@ unsafe impl<T> SliceIndex<[T]> for usize { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +unsafe impl<T> const SliceIndex<[T]> for ops::Range<usize> { type Output = [T]; #[inline] @@ -261,7 +304,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::Range<usize> { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +unsafe impl<T> const SliceIndex<[T]> for ops::RangeTo<usize> { type Output = [T]; #[inline] @@ -298,7 +342,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeTo<usize> { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +unsafe impl<T> const SliceIndex<[T]> for ops::RangeFrom<usize> { type Output = [T]; #[inline] @@ -343,7 +388,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFrom<usize> { } #[stable(feature = "slice_get_slice_impls", since = "1.15.0")] -unsafe impl<T> SliceIndex<[T]> for ops::RangeFull { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +unsafe impl<T> const SliceIndex<[T]> for ops::RangeFull { type Output = [T]; #[inline] @@ -378,7 +424,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeFull { } #[stable(feature = "inclusive_range", since = "1.26.0")] -unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +unsafe impl<T> const SliceIndex<[T]> for ops::RangeInclusive<usize> { type Output = [T]; #[inline] @@ -421,7 +468,8 @@ unsafe impl<T> SliceIndex<[T]> for ops::RangeInclusive<usize> { } #[stable(feature = "inclusive_range", since = "1.26.0")] -unsafe impl<T> SliceIndex<[T]> for ops::RangeToInclusive<usize> { +#[rustc_const_unstable(feature = "const_slice_index_impls", issue = "none")] +unsafe impl<T> const SliceIndex<[T]> for ops::RangeToInclusive<usize> { type Output = [T]; #[inline] |
