about summary refs log tree commit diff
diff options
context:
space:
mode:
authorSimonas Kazlauskas <git@kazlauskas.me>2020-10-10 00:25:28 +0300
committerSimonas Kazlauskas <git@kazlauskas.me>2020-10-10 00:56:45 +0300
commit54a560833451324194b51e906c50a9122a3d97fc (patch)
tree0e07283da9b76047ee06f60c5bed1eed1753bafb
parent5ddef544fa26c5535376fa424baf30cb985f7cb1 (diff)
downloadrust-54a560833451324194b51e906c50a9122a3d97fc.tar.gz
rust-54a560833451324194b51e906c50a9122a3d97fc.zip
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 e44784b8750016a695361c990024750e037d8f9f / #77023.
-rw-r--r--library/core/src/lib.rs1
-rw-r--r--library/core/src/slice/mod.rs23
-rw-r--r--src/test/codegen/len-is-bounded.rs24
3 files changed, 2 insertions, 46 deletions
diff --git a/library/core/src/lib.rs b/library/core/src/lib.rs
index 960a26fd283..c9a80b5bc77 100644
--- a/library/core/src/lib.rs
+++ b/library/core/src/lib.rs
@@ -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)]
diff --git a/library/core/src/slice/mod.rs b/library/core/src/slice/mod.rs
index 13d0dda19c7..d0d88c01f5b 100644
--- a/library/core/src/slice/mod.rs
+++ b/library/core/src/slice/mod.rs
@@ -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.
diff --git a/src/test/codegen/len-is-bounded.rs b/src/test/codegen/len-is-bounded.rs
deleted file mode 100644
index bb74fc3b275..00000000000
--- a/src/test/codegen/len-is-bounded.rs
+++ /dev/null
@@ -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()
-}