Revert "Assume slice len is bounded by allocation size"

https://github.com/rust-lang/rust/pull/77023#issuecomment-703987379
suggests that the original PR introduced a significant perf regression.

This reverts commit e44784b875 / #77023.
This commit is contained in:
Simonas Kazlauskas 2020-10-10 00:25:28 +03:00
parent 5ddef544fa
commit 54a5608334
3 changed files with 2 additions and 46 deletions

View File

@ -82,7 +82,6 @@
#![feature(const_pin)]
#![feature(const_fn)]
#![feature(const_fn_union)]
#![feature(const_assume)]
#![cfg_attr(not(bootstrap), feature(const_impl_trait))]
#![feature(const_fn_floating_point_arithmetic)]
#![feature(const_fn_fn_ptr_basics)]

View File

@ -79,16 +79,6 @@ pub use index::check_range;
#[lang = "slice"]
#[cfg(not(test))]
impl<T> [T] {
/// The maximum, inclusive, length such that the slice is no larger than `isize::MAX` bytes.
/// This constant is used in `len` below.
const MAX_LEN_BOUND: usize = {
if mem::size_of::<T>() == 0 {
usize::MAX
} else {
isize::MAX as usize / mem::size_of::<T>()
}
};
/// Returns the number of elements in the slice.
///
/// # Examples
@ -101,20 +91,11 @@ impl<T> [T] {
#[rustc_const_stable(feature = "const_slice_len", since = "1.32.0")]
#[inline]
// SAFETY: const sound because we transmute out the length field as a usize (which it must be)
#[allow_internal_unstable(const_fn_union, const_assume)]
#[allow_internal_unstable(const_fn_union)]
pub const fn len(&self) -> usize {
// SAFETY: this is safe because `&[T]` and `FatPtr<T>` have the same layout.
// Only `std` can make this guarantee.
let raw_len = unsafe { crate::ptr::Repr { rust: self }.raw.len };
// SAFETY: this assume asserts that `raw_len * size_of::<T>() <= isize::MAX`. All
// references must point to one allocation with size at most isize::MAX. Note that we the
// multiplication could appear to overflow until we have assumed the bound. This overflow
// would make additional values appear 'valid' and then `n > 1` the range of permissible
// length would no longer be the full or even a single range.
unsafe { crate::intrinsics::assume(raw_len <= Self::MAX_LEN_BOUND) };
raw_len
unsafe { crate::ptr::Repr { rust: self }.raw.len }
}
/// Returns `true` if the slice has a length of 0.

View File

@ -1,24 +0,0 @@
// min-llvm-version: 11.0
// compile-flags: -O -C panic=abort
#![crate_type = "lib"]
#[no_mangle]
pub fn len_range(a: &[u8], b: &[u8]) -> usize {
// CHECK-NOT: panic
a.len().checked_add(b.len()).unwrap()
}
#[no_mangle]
pub fn len_range_on_non_byte(a: &[u16], b: &[u16]) -> usize {
// CHECK-NOT: panic
a.len().checked_add(b.len()).unwrap()
}
pub struct Zst;
#[no_mangle]
pub fn zst_range(a: &[Zst], b: &[Zst]) -> usize {
// Zsts may be arbitrarily large.
// CHECK: panic
a.len().checked_add(b.len()).unwrap()
}