Constify slice indexing

This commit is contained in:
Deadbeef 2022-02-22 12:39:36 +11:00
parent 03a8cc7df1
commit 5941fef292
No known key found for this signature in database
GPG key ID: 6D017A96D8E6C2F9
3 changed files with 71 additions and 22 deletions

View file

@ -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)]

View file

@ -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.

View file

@ -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 @@ fn index(&self, index: I) -> &I::Output {
}
#[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 @@ fn index_mut(&mut self, index: I) -> &mut I::Output {
}
}
#[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);
}
#[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) -> ! {
panic!("slice index starts at {} but ends at {}", index, end);
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_start_index_overflow_fail() -> ! {
#[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]
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 @@ fn index_mut(self, slice: &mut [T]) -> &mut T {
}
#[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 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
#[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 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
#[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 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
#[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 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
#[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 @@ fn index_mut(self, slice: &mut [T]) -> &mut [T] {
}
#[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]