about summary refs log tree commit diff
diff options
context:
space:
mode:
authorDeadbeef <ent3rm4n@gmail.com>2022-02-22 12:39:36 +1100
committerDeadbeef <ent3rm4n@gmail.com>2022-02-22 12:39:36 +1100
commit5941fef2920a631b22e870627c67a2cd9c30dafe (patch)
treedf57813ffacba5555eb44c27d4dd9e81afe1486b
parent03a8cc7df1d65554a4d40825b0490c93ac0f0236 (diff)
downloadrust-5941fef2920a631b22e870627c67a2cd9c30dafe.tar.gz
rust-5941fef2920a631b22e870627c67a2cd9c30dafe.zip
Constify slice indexing
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/ops/range.rs2
-rw-r--r--library/core/src/slice/index.rs80
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]