about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNathan Perry <np@nathanperry.dev>2024-07-30 09:48:36 -0400
committerNathan Perry <np@nathanperry.dev>2024-10-06 19:58:35 -0400
commitd793766a6199d9b7339633ad0296af63c7b4f9b8 (patch)
tree788a504d400cd51964d6db63634f1b6a33e05e11
parent506f22b4663f3e756e1e6a4f66c6309fdc00819c (diff)
downloadrust-d793766a6199d9b7339633ad0296af63c7b4f9b8.tar.gz
rust-d793766a6199d9b7339633ad0296af63c7b4f9b8.zip
liballoc: introduce String, Vec const-slicing
This change `const`-qualifies many methods on Vec and String, notably
`as_slice`, `as_str`, `len`. These changes are made behind the unstable
feature flag `const_vec_string_slice` with the following tracking issue:

https://github.com/rust-lang/rust/issues/129041
-rw-r--r--library/alloc/src/lib.rs1
-rw-r--r--library/alloc/src/raw_vec.rs12
-rw-r--r--library/alloc/src/string.rs38
-rw-r--r--library/alloc/src/vec/mod.rs55
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir91
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir91
-rw-r--r--tests/ui/consts/issue-94675.rs2
-rw-r--r--tests/ui/consts/issue-94675.stderr10
8 files changed, 164 insertions, 136 deletions
diff --git a/library/alloc/src/lib.rs b/library/alloc/src/lib.rs
index f0597f295b3..4a09b5dfd17 100644
--- a/library/alloc/src/lib.rs
+++ b/library/alloc/src/lib.rs
@@ -114,6 +114,7 @@
 #![feature(const_option)]
 #![feature(const_pin)]
 #![feature(const_size_of_val)]
+#![feature(const_vec_string_slice)]
 #![feature(core_intrinsics)]
 #![feature(deprecated_suggestion)]
 #![feature(deref_pure_trait)]
diff --git a/library/alloc/src/raw_vec.rs b/library/alloc/src/raw_vec.rs
index 436e0596e3d..8fdca8c4200 100644
--- a/library/alloc/src/raw_vec.rs
+++ b/library/alloc/src/raw_vec.rs
@@ -280,7 +280,7 @@ impl<T, A: Allocator> RawVec<T, A> {
     /// `Unique::dangling()` if `capacity == 0` or `T` is zero-sized. In the former case, you must
     /// be careful.
     #[inline]
-    pub fn ptr(&self) -> *mut T {
+    pub const fn ptr(&self) -> *mut T {
         self.inner.ptr()
     }
 
@@ -293,7 +293,7 @@ impl<T, A: Allocator> RawVec<T, A> {
     ///
     /// This will always be `usize::MAX` if `T` is zero-sized.
     #[inline]
-    pub fn capacity(&self) -> usize {
+    pub const fn capacity(&self) -> usize {
         self.inner.capacity(size_of::<T>())
     }
 
@@ -488,17 +488,17 @@ impl<A: Allocator> RawVecInner<A> {
     }
 
     #[inline]
-    fn ptr<T>(&self) -> *mut T {
+    const fn ptr<T>(&self) -> *mut T {
         self.non_null::<T>().as_ptr()
     }
 
     #[inline]
-    fn non_null<T>(&self) -> NonNull<T> {
-        self.ptr.cast().into()
+    const fn non_null<T>(&self) -> NonNull<T> {
+        self.ptr.cast().as_non_null_ptr()
     }
 
     #[inline]
-    fn capacity(&self, elem_size: usize) -> usize {
+    const fn capacity(&self, elem_size: usize) -> usize {
         if elem_size == 0 { usize::MAX } else { self.cap.0 }
     }
 
diff --git a/library/alloc/src/string.rs b/library/alloc/src/string.rs
index d58a016b502..2815ea4da7f 100644
--- a/library/alloc/src/string.rs
+++ b/library/alloc/src/string.rs
@@ -1059,7 +1059,8 @@ impl String {
     #[inline]
     #[must_use = "`self` will be dropped if the result is not used"]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn into_bytes(self) -> Vec<u8> {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn into_bytes(self) -> Vec<u8> {
         self.vec
     }
 
@@ -1076,8 +1077,11 @@ impl String {
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_str")]
-    pub fn as_str(&self) -> &str {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_str(&self) -> &str {
+        // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
+        // at construction.
+        unsafe { str::from_utf8_unchecked(self.vec.as_slice()) }
     }
 
     /// Converts a `String` into a mutable string slice.
@@ -1096,8 +1100,11 @@ impl String {
     #[must_use]
     #[stable(feature = "string_as_str", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "string_as_mut_str")]
-    pub fn as_mut_str(&mut self) -> &mut str {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_mut_str(&mut self) -> &mut str {
+        // SAFETY: String contents are stipulated to be valid UTF-8, invalid contents are an error
+        // at construction.
+        unsafe { str::from_utf8_unchecked_mut(self.vec.as_mut_slice()) }
     }
 
     /// Appends a given string slice onto the end of this `String`.
@@ -1168,7 +1175,8 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn capacity(&self) -> usize {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn capacity(&self) -> usize {
         self.vec.capacity()
     }
 
@@ -1431,8 +1439,9 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn as_bytes(&self) -> &[u8] {
-        &self.vec
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_bytes(&self) -> &[u8] {
+        self.vec.as_slice()
     }
 
     /// Shortens this `String` to the specified length.
@@ -1784,7 +1793,8 @@ impl String {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const unsafe fn as_mut_vec(&mut self) -> &mut Vec<u8> {
         &mut self.vec
     }
 
@@ -1805,8 +1815,9 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_confusables("length", "size")]
-    pub fn len(&self) -> usize {
+    pub const fn len(&self) -> usize {
         self.vec.len()
     }
 
@@ -1824,7 +1835,8 @@ impl String {
     #[inline]
     #[must_use]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn is_empty(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
 
@@ -2565,7 +2577,7 @@ impl ops::Deref for String {
 
     #[inline]
     fn deref(&self) -> &str {
-        unsafe { str::from_utf8_unchecked(&self.vec) }
+        self.as_str()
     }
 }
 
@@ -2576,7 +2588,7 @@ unsafe impl ops::DerefPure for String {}
 impl ops::DerefMut for String {
     #[inline]
     fn deref_mut(&mut self) -> &mut str {
-        unsafe { str::from_utf8_unchecked_mut(&mut *self.vec) }
+        self.as_mut_str()
     }
 }
 
diff --git a/library/alloc/src/vec/mod.rs b/library/alloc/src/vec/mod.rs
index 13b06584223..cae47393a81 100644
--- a/library/alloc/src/vec/mod.rs
+++ b/library/alloc/src/vec/mod.rs
@@ -1240,7 +1240,8 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
-    pub fn capacity(&self) -> usize {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn capacity(&self) -> usize {
         self.buf.capacity()
     }
 
@@ -1548,8 +1549,22 @@ impl<T, A: Allocator> Vec<T, A> {
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_slice")]
-    pub fn as_slice(&self) -> &[T] {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_slice(&self) -> &[T] {
+        // SAFETY: `slice::from_raw_parts` requires pointee is a contiguous, aligned buffer of size
+        // `len` containing properly-initialized `T`s. Data must not be mutated for the returned
+        // lifetime. Further, `len * mem::size_of::<T>` <= `ISIZE::MAX`, and allocation does not
+        // "wrap" through overflowing memory addresses.
+        //
+        // * Vec API guarantees that self.buf:
+        //      * contains only properly-initialized items within 0..len
+        //      * is aligned, contiguous, and valid for `len` reads
+        //      * obeys size and address-wrapping constraints
+        //
+        // * We only construct `&mut` references to `self.buf` through `&mut self` methods; borrow-
+        //   check ensures that it is not possible to mutably alias `self.buf` within the
+        //   returned lifetime.
+        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
     }
 
     /// Extracts a mutable slice of the entire vector.
@@ -1566,8 +1581,22 @@ impl<T, A: Allocator> Vec<T, A> {
     #[inline]
     #[stable(feature = "vec_as_slice", since = "1.7.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "vec_as_mut_slice")]
-    pub fn as_mut_slice(&mut self) -> &mut [T] {
-        self
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn as_mut_slice(&mut self) -> &mut [T] {
+        // SAFETY: `slice::from_raw_parts_mut` requires pointee is a contiguous, aligned buffer of
+        // size `len` containing properly-initialized `T`s. Data must not be accessed through any
+        // other pointer for the returned lifetime. Further, `len * mem::size_of::<T>` <=
+        // `ISIZE::MAX` and allocation does not "wrap" through overflowing memory addresses.
+        //
+        // * Vec API guarantees that self.buf:
+        //      * contains only properly-initialized items within 0..len
+        //      * is aligned, contiguous, and valid for `len` reads
+        //      * obeys size and address-wrapping constraints
+        //
+        // * We only construct references to `self.buf` through `&self` and `&mut self` methods;
+        //   borrow-check ensures that it is not possible to construct a reference to `self.buf`
+        //   within the returned lifetime.
+        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
     }
 
     /// Returns a raw pointer to the vector's buffer, or a dangling raw pointer
@@ -1622,9 +1651,10 @@ impl<T, A: Allocator> Vec<T, A> {
     /// [`as_mut_ptr`]: Vec::as_mut_ptr
     /// [`as_ptr`]: Vec::as_ptr
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_never_returns_null_ptr]
     #[inline]
-    pub fn as_ptr(&self) -> *const T {
+    pub const fn as_ptr(&self) -> *const T {
         // We shadow the slice method of the same name to avoid going through
         // `deref`, which creates an intermediate reference.
         self.buf.ptr()
@@ -1681,9 +1711,10 @@ impl<T, A: Allocator> Vec<T, A> {
     /// [`as_mut_ptr`]: Vec::as_mut_ptr
     /// [`as_ptr`]: Vec::as_ptr
     #[stable(feature = "vec_as_ptr", since = "1.37.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_never_returns_null_ptr]
     #[inline]
-    pub fn as_mut_ptr(&mut self) -> *mut T {
+    pub const fn as_mut_ptr(&mut self) -> *mut T {
         // We shadow the slice method of the same name to avoid going through
         // `deref_mut`, which creates an intermediate reference.
         self.buf.ptr()
@@ -2561,8 +2592,9 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[inline]
     #[stable(feature = "rust1", since = "1.0.0")]
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
     #[rustc_confusables("length", "size")]
-    pub fn len(&self) -> usize {
+    pub const fn len(&self) -> usize {
         self.len
     }
 
@@ -2579,7 +2611,8 @@ impl<T, A: Allocator> Vec<T, A> {
     /// ```
     #[stable(feature = "rust1", since = "1.0.0")]
     #[cfg_attr(not(test), rustc_diagnostic_item = "vec_is_empty")]
-    pub fn is_empty(&self) -> bool {
+    #[rustc_const_unstable(feature = "const_vec_string_slice", issue = "129041")]
+    pub const fn is_empty(&self) -> bool {
         self.len() == 0
     }
 
@@ -3130,7 +3163,7 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
 
     #[inline]
     fn deref(&self) -> &[T] {
-        unsafe { slice::from_raw_parts(self.as_ptr(), self.len) }
+        self.as_slice()
     }
 }
 
@@ -3138,7 +3171,7 @@ impl<T, A: Allocator> ops::Deref for Vec<T, A> {
 impl<T, A: Allocator> ops::DerefMut for Vec<T, A> {
     #[inline]
     fn deref_mut(&mut self) -> &mut [T] {
-        unsafe { slice::from_raw_parts_mut(self.as_mut_ptr(), self.len) }
+        self.as_mut_slice()
     }
 }
 
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
index 0ad7f5910a0..4d964b0afb7 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
@@ -5,66 +5,61 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     let mut _0: &[u8];
     scope 1 (inlined <Vec<u8> as Deref>::deref) {
         debug self => _1;
-        let mut _6: usize;
-        scope 2 (inlined Vec::<u8>::as_ptr) {
+        scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _2: &alloc::raw_vec::RawVec<u8>;
-            scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
-                debug self => _2;
-                let mut _3: &alloc::raw_vec::RawVecInner;
-                scope 4 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                    debug self => _3;
-                    scope 5 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+            let mut _6: usize;
+            scope 3 (inlined Vec::<u8>::as_ptr) {
+                debug self => _1;
+                let mut _2: &alloc::raw_vec::RawVec<u8>;
+                scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
+                    debug self => _2;
+                    let mut _3: &alloc::raw_vec::RawVecInner;
+                    scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
-                        let mut _4: std::ptr::NonNull<u8>;
-                        scope 6 (inlined Unique::<u8>::cast::<u8>) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 7 (inlined NonNull::<u8>::cast::<u8>) {
-                                debug self => _4;
-                                scope 8 (inlined NonNull::<u8>::as_ptr) {
+                        scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+                            debug self => _3;
+                            let mut _4: std::ptr::NonNull<u8>;
+                            scope 7 (inlined Unique::<u8>::cast::<u8>) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
+                                scope 8 (inlined NonNull::<u8>::cast::<u8>) {
                                     debug self => _4;
-                                    let mut _5: *const u8;
+                                    scope 9 (inlined NonNull::<u8>::as_ptr) {
+                                        debug self => _4;
+                                        let mut _5: *const u8;
+                                    }
                                 }
                             }
-                        }
-                        scope 9 (inlined #[track_caller] <Unique<u8> as Into<NonNull<u8>>>::into) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 10 (inlined <NonNull<u8> as From<Unique<u8>>>::from) {
-                                debug ((unique: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                debug ((unique: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                scope 11 (inlined Unique::<u8>::as_non_null_ptr) {
-                                    debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                    debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                }
+                            scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
+                        scope 11 (inlined NonNull::<u8>::as_ptr) {
+                            debug self => _4;
+                        }
                     }
-                    scope 12 (inlined NonNull::<u8>::as_ptr) {
-                        debug self => _4;
-                    }
-                }
-            }
-        }
-        scope 13 (inlined std::slice::from_raw_parts::<'_, u8>) {
-            debug data => _5;
-            debug len => _6;
-            let _7: *const [u8];
-            scope 14 (inlined core::ub_checks::check_language_ub) {
-                scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
-            scope 16 (inlined std::mem::size_of::<u8>) {
-            }
-            scope 17 (inlined align_of::<u8>) {
-            }
-            scope 18 (inlined slice_from_raw_parts::<u8>) {
+            scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
                 debug data => _5;
                 debug len => _6;
-                scope 19 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                    debug data_pointer => _5;
-                    debug metadata => _6;
+                let _7: *const [u8];
+                scope 13 (inlined core::ub_checks::check_language_ub) {
+                    scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
+                    }
+                }
+                scope 15 (inlined std::mem::size_of::<u8>) {
+                }
+                scope 16 (inlined align_of::<u8>) {
+                }
+                scope 17 (inlined slice_from_raw_parts::<u8>) {
+                    debug data => _5;
+                    debug len => _6;
+                    scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
+                        debug data_pointer => _5;
+                        debug metadata => _6;
+                    }
                 }
             }
         }
diff --git a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
index 0ad7f5910a0..4d964b0afb7 100644
--- a/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
@@ -5,66 +5,61 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     let mut _0: &[u8];
     scope 1 (inlined <Vec<u8> as Deref>::deref) {
         debug self => _1;
-        let mut _6: usize;
-        scope 2 (inlined Vec::<u8>::as_ptr) {
+        scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _2: &alloc::raw_vec::RawVec<u8>;
-            scope 3 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
-                debug self => _2;
-                let mut _3: &alloc::raw_vec::RawVecInner;
-                scope 4 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
-                    debug self => _3;
-                    scope 5 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+            let mut _6: usize;
+            scope 3 (inlined Vec::<u8>::as_ptr) {
+                debug self => _1;
+                let mut _2: &alloc::raw_vec::RawVec<u8>;
+                scope 4 (inlined alloc::raw_vec::RawVec::<u8>::ptr) {
+                    debug self => _2;
+                    let mut _3: &alloc::raw_vec::RawVecInner;
+                    scope 5 (inlined alloc::raw_vec::RawVecInner::ptr::<u8>) {
                         debug self => _3;
-                        let mut _4: std::ptr::NonNull<u8>;
-                        scope 6 (inlined Unique::<u8>::cast::<u8>) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 7 (inlined NonNull::<u8>::cast::<u8>) {
-                                debug self => _4;
-                                scope 8 (inlined NonNull::<u8>::as_ptr) {
+                        scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
+                            debug self => _3;
+                            let mut _4: std::ptr::NonNull<u8>;
+                            scope 7 (inlined Unique::<u8>::cast::<u8>) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
+                                scope 8 (inlined NonNull::<u8>::cast::<u8>) {
                                     debug self => _4;
-                                    let mut _5: *const u8;
+                                    scope 9 (inlined NonNull::<u8>::as_ptr) {
+                                        debug self => _4;
+                                        let mut _5: *const u8;
+                                    }
                                 }
                             }
-                        }
-                        scope 9 (inlined #[track_caller] <Unique<u8> as Into<NonNull<u8>>>::into) {
-                            debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                            debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                            scope 10 (inlined <NonNull<u8> as From<Unique<u8>>>::from) {
-                                debug ((unique: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                debug ((unique: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                scope 11 (inlined Unique::<u8>::as_non_null_ptr) {
-                                    debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
-                                    debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
-                                }
+                            scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _4;
+                                debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
+                        scope 11 (inlined NonNull::<u8>::as_ptr) {
+                            debug self => _4;
+                        }
                     }
-                    scope 12 (inlined NonNull::<u8>::as_ptr) {
-                        debug self => _4;
-                    }
-                }
-            }
-        }
-        scope 13 (inlined std::slice::from_raw_parts::<'_, u8>) {
-            debug data => _5;
-            debug len => _6;
-            let _7: *const [u8];
-            scope 14 (inlined core::ub_checks::check_language_ub) {
-                scope 15 (inlined core::ub_checks::check_language_ub::runtime) {
                 }
             }
-            scope 16 (inlined std::mem::size_of::<u8>) {
-            }
-            scope 17 (inlined align_of::<u8>) {
-            }
-            scope 18 (inlined slice_from_raw_parts::<u8>) {
+            scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
                 debug data => _5;
                 debug len => _6;
-                scope 19 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                    debug data_pointer => _5;
-                    debug metadata => _6;
+                let _7: *const [u8];
+                scope 13 (inlined core::ub_checks::check_language_ub) {
+                    scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
+                    }
+                }
+                scope 15 (inlined std::mem::size_of::<u8>) {
+                }
+                scope 16 (inlined align_of::<u8>) {
+                }
+                scope 17 (inlined slice_from_raw_parts::<u8>) {
+                    debug data => _5;
+                    debug len => _6;
+                    scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
+                        debug data_pointer => _5;
+                        debug metadata => _6;
+                    }
                 }
             }
         }
diff --git a/tests/ui/consts/issue-94675.rs b/tests/ui/consts/issue-94675.rs
index 56c4b6ea36f..2e30eebb07b 100644
--- a/tests/ui/consts/issue-94675.rs
+++ b/tests/ui/consts/issue-94675.rs
@@ -1,6 +1,6 @@
 //@ known-bug: #103507
 
-#![feature(const_trait_impl)]
+#![feature(const_trait_impl, const_vec_string_slice)]
 
 struct Foo<'a> {
     bar: &'a mut Vec<usize>,
diff --git a/tests/ui/consts/issue-94675.stderr b/tests/ui/consts/issue-94675.stderr
index ebfa09b2e5d..a85c5e10374 100644
--- a/tests/ui/consts/issue-94675.stderr
+++ b/tests/ui/consts/issue-94675.stderr
@@ -1,11 +1,3 @@
-error[E0015]: cannot call non-const fn `Vec::<u32>::len` in constant functions
-  --> $DIR/issue-94675.rs:11:27
-   |
-LL |         self.bar[0] = baz.len();
-   |                           ^^^^^
-   |
-   = note: calls in constant functions are limited to constant functions, tuple structs and tuple variants
-
 error[E0015]: cannot call non-const operator in constant functions
   --> $DIR/issue-94675.rs:11:17
    |
@@ -20,6 +12,6 @@ help: add `#![feature(effects)]` to the crate attributes to enable
 LL + #![feature(effects)]
    |
 
-error: aborting due to 2 previous errors
+error: aborting due to 1 previous error
 
 For more information about this error, try `rustc --explain E0015`.