about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMatthias Krüger <matthias.krueger@famsik.de>2024-12-04 05:42:07 +0100
committerGitHub <noreply@github.com>2024-12-04 05:42:07 +0100
commit68f8a53f124642c8c1e810b7efe40e31718732b0 (patch)
tree3d185937d3046d93c3dcb742a227363455aa284e
parent3b382642aba7cffbb2f47829b24635fad87bcf5c (diff)
parent7afce4f06a56dc1344f54e179a0785b95700df5f (diff)
downloadrust-68f8a53f124642c8c1e810b7efe40e31718732b0.tar.gz
rust-68f8a53f124642c8c1e810b7efe40e31718732b0.zip
Rollup merge of #133651 - scottmcm:nonnull-nonzero-no-field-projection, r=oli-obk
Update `NonZero` and `NonNull` to not field-project (per MCP#807)

https://github.com/rust-lang/compiler-team/issues/807#issuecomment-2506098540 was accepted, so this is the first PR towards moving the library to not using field projections into `[rustc_layout_scalar_valid_range_*]` types.

`NonZero` was already using `transmute` nearly everywhere, so there are very few changes to it.

`NonNull` needed more changes, but they're mostly simple, changing `.pointer` to `.as_ptr()`.

r? libs

cc #133324, which will tidy up some of the MIR from this a bit more, but isn't a blocker.
-rw-r--r--library/core/src/num/nonzero.rs34
-rw-r--r--library/core/src/ptr/non_null.rs53
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff12
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff12
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff12
-rw-r--r--tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff12
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir184
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir134
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir118
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir118
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir132
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir132
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir12
-rw-r--r--tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir12
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir58
-rw-r--r--tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir58
16 files changed, 583 insertions, 510 deletions
diff --git a/library/core/src/num/nonzero.rs b/library/core/src/num/nonzero.rs
index e97af081143..a9294306b1b 100644
--- a/library/core/src/num/nonzero.rs
+++ b/library/core/src/num/nonzero.rs
@@ -37,6 +37,8 @@ pub unsafe trait ZeroablePrimitive: Sized + Copy + private::Sealed {
 macro_rules! impl_zeroable_primitive {
     ($($NonZeroInner:ident ( $primitive:ty )),+ $(,)?) => {
         mod private {
+            use super::*;
+
             #[unstable(
                 feature = "nonzero_internals",
                 reason = "implementation detail which may disappear or be replaced at any time",
@@ -45,7 +47,11 @@ macro_rules! impl_zeroable_primitive {
             pub trait Sealed {}
 
             $(
-                #[derive(Debug, Clone, Copy, PartialEq)]
+                // This inner type is never shown directly, so intentionally does not have Debug
+                #[expect(missing_debug_implementations)]
+                // Since this struct is non-generic and derives Copy,
+                // the derived Clone is `*self` and thus doesn't field-project.
+                #[derive(Clone, Copy)]
                 #[repr(transparent)]
                 #[rustc_layout_scalar_valid_range_start(1)]
                 #[rustc_nonnull_optimization_guaranteed]
@@ -55,6 +61,16 @@ macro_rules! impl_zeroable_primitive {
                     issue = "none"
                 )]
                 pub struct $NonZeroInner($primitive);
+
+                // This is required to allow matching a constant.  We don't get it from a derive
+                // because the derived `PartialEq` would do a field projection, which is banned
+                // by <https://github.com/rust-lang/compiler-team/issues/807>.
+                #[unstable(
+                    feature = "nonzero_internals",
+                    reason = "implementation detail which may disappear or be replaced at any time",
+                    issue = "none"
+                )]
+                impl StructuralPartialEq for $NonZeroInner {}
             )+
         }
 
@@ -172,7 +188,7 @@ where
 {
     #[inline]
     fn clone(&self) -> Self {
-        Self(self.0)
+        *self
     }
 }
 
@@ -440,15 +456,21 @@ where
     #[rustc_const_stable(feature = "const_nonzero_get", since = "1.34.0")]
     #[inline]
     pub const fn get(self) -> T {
-        // FIXME: This can be changed to simply `self.0` once LLVM supports `!range` metadata
-        // for function arguments: https://github.com/llvm/llvm-project/issues/76628
-        //
         // Rustc can set range metadata only if it loads `self` from
         // memory somewhere. If the value of `self` was from by-value argument
         // of some not-inlined function, LLVM don't have range metadata
         // to understand that the value cannot be zero.
         //
-        // For now, using the transmute `assume`s the range at runtime.
+        // Using the transmute `assume`s the range at runtime.
+        //
+        // Even once LLVM supports `!range` metadata for function arguments
+        // (see <https://github.com/llvm/llvm-project/issues/76628>), this can't
+        // be `.0` because MCP#807 bans field-projecting into `scalar_valid_range`
+        // types, and it arguably wouldn't want to be anyway because if this is
+        // MIR-inlined, there's no opportunity to put that argument metadata anywhere.
+        //
+        // The good answer here will eventually be pattern types, which will hopefully
+        // allow it to go back to `.0`, maybe with a cast of some sort.
         //
         // SAFETY: `ZeroablePrimitive` guarantees that the size and bit validity
         // of `.0` is such that this transmute is sound.
diff --git a/library/core/src/ptr/non_null.rs b/library/core/src/ptr/non_null.rs
index d37b7eedfcb..0ad1cad6914 100644
--- a/library/core/src/ptr/non_null.rs
+++ b/library/core/src/ptr/non_null.rs
@@ -7,7 +7,7 @@ use crate::pin::PinCoerceUnsized;
 use crate::ptr::Unique;
 use crate::slice::{self, SliceIndex};
 use crate::ub_checks::assert_unsafe_precondition;
-use crate::{fmt, hash, intrinsics, ptr};
+use crate::{fmt, hash, intrinsics, mem, ptr};
 
 /// `*mut T` but non-zero and [covariant].
 ///
@@ -69,6 +69,8 @@ use crate::{fmt, hash, intrinsics, ptr};
 #[rustc_nonnull_optimization_guaranteed]
 #[rustc_diagnostic_item = "NonNull"]
 pub struct NonNull<T: ?Sized> {
+    // Remember to use `.as_ptr()` instead of `.pointer`, as field projecting to
+    // this is banned by <https://github.com/rust-lang/compiler-team/issues/807>.
     pointer: *const T,
 }
 
@@ -282,7 +284,7 @@ impl<T: ?Sized> NonNull<T> {
     pub fn addr(self) -> NonZero<usize> {
         // SAFETY: The pointer is guaranteed by the type to be non-null,
         // meaning that the address will be non-zero.
-        unsafe { NonZero::new_unchecked(self.pointer.addr()) }
+        unsafe { NonZero::new_unchecked(self.as_ptr().addr()) }
     }
 
     /// Creates a new pointer with the given address and the [provenance][crate::ptr#provenance] of
@@ -296,7 +298,7 @@ impl<T: ?Sized> NonNull<T> {
     #[stable(feature = "strict_provenance", since = "1.84.0")]
     pub fn with_addr(self, addr: NonZero<usize>) -> Self {
         // SAFETY: The result of `ptr::from::with_addr` is non-null because `addr` is guaranteed to be non-zero.
-        unsafe { NonNull::new_unchecked(self.pointer.with_addr(addr.get()) as *mut _) }
+        unsafe { NonNull::new_unchecked(self.as_ptr().with_addr(addr.get()) as *mut _) }
     }
 
     /// Creates a new pointer by mapping `self`'s address to a new one, preserving the
@@ -335,7 +337,12 @@ impl<T: ?Sized> NonNull<T> {
     #[must_use]
     #[inline(always)]
     pub const fn as_ptr(self) -> *mut T {
-        self.pointer as *mut T
+        // This is a transmute for the same reasons as `NonZero::get`.
+
+        // SAFETY: `NonNull` is `transparent` over a `*const T`, and `*const T`
+        // and `*mut T` have the same layout, so transitively we can transmute
+        // our `NonNull` to a `*mut T` directly.
+        unsafe { mem::transmute::<Self, *mut T>(self) }
     }
 
     /// Returns a shared reference to the value. If the value may be uninitialized, [`as_uninit_ref`]
@@ -484,7 +491,7 @@ impl<T: ?Sized> NonNull<T> {
         // Additionally safety contract of `offset` guarantees that the resulting pointer is
         // pointing to an allocation, there can't be an allocation at null, thus it's safe to
         // construct `NonNull`.
-        unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } }
+        unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
     }
 
     /// Calculates the offset from a pointer in bytes.
@@ -508,7 +515,7 @@ impl<T: ?Sized> NonNull<T> {
         // Additionally safety contract of `offset` guarantees that the resulting pointer is
         // pointing to an allocation, there can't be an allocation at null, thus it's safe to
         // construct `NonNull`.
-        unsafe { NonNull { pointer: self.pointer.byte_offset(count) } }
+        unsafe { NonNull { pointer: self.as_ptr().byte_offset(count) } }
     }
 
     /// Adds an offset to a pointer (convenience for `.offset(count as isize)`).
@@ -560,7 +567,7 @@ impl<T: ?Sized> NonNull<T> {
         // Additionally safety contract of `offset` guarantees that the resulting pointer is
         // pointing to an allocation, there can't be an allocation at null, thus it's safe to
         // construct `NonNull`.
-        unsafe { NonNull { pointer: intrinsics::offset(self.pointer, count) } }
+        unsafe { NonNull { pointer: intrinsics::offset(self.as_ptr(), count) } }
     }
 
     /// Calculates the offset from a pointer in bytes (convenience for `.byte_offset(count as isize)`).
@@ -584,7 +591,7 @@ impl<T: ?Sized> NonNull<T> {
         // Additionally safety contract of `add` guarantees that the resulting pointer is pointing
         // to an allocation, there can't be an allocation at null, thus it's safe to construct
         // `NonNull`.
-        unsafe { NonNull { pointer: self.pointer.byte_add(count) } }
+        unsafe { NonNull { pointer: self.as_ptr().byte_add(count) } }
     }
 
     /// Subtracts an offset from a pointer (convenience for
@@ -666,7 +673,7 @@ impl<T: ?Sized> NonNull<T> {
         // Additionally safety contract of `sub` guarantees that the resulting pointer is pointing
         // to an allocation, there can't be an allocation at null, thus it's safe to construct
         // `NonNull`.
-        unsafe { NonNull { pointer: self.pointer.byte_sub(count) } }
+        unsafe { NonNull { pointer: self.as_ptr().byte_sub(count) } }
     }
 
     /// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -763,7 +770,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `offset_from`.
-        unsafe { self.pointer.offset_from(origin.pointer) }
+        unsafe { self.as_ptr().offset_from(origin.as_ptr()) }
     }
 
     /// Calculates the distance between two pointers within the same allocation. The returned value is in
@@ -781,7 +788,7 @@ impl<T: ?Sized> NonNull<T> {
     #[rustc_const_stable(feature = "non_null_convenience", since = "1.80.0")]
     pub const unsafe fn byte_offset_from<U: ?Sized>(self, origin: NonNull<U>) -> isize {
         // SAFETY: the caller must uphold the safety contract for `byte_offset_from`.
-        unsafe { self.pointer.byte_offset_from(origin.pointer) }
+        unsafe { self.as_ptr().byte_offset_from(origin.as_ptr()) }
     }
 
     // N.B. `wrapping_offset``, `wrapping_add`, etc are not implemented because they can wrap to null
@@ -856,7 +863,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `sub_ptr`.
-        unsafe { self.pointer.sub_ptr(subtracted.pointer) }
+        unsafe { self.as_ptr().sub_ptr(subtracted.as_ptr()) }
     }
 
     /// Calculates the distance between two pointers within the same allocation, *where it's known that
@@ -875,7 +882,7 @@ impl<T: ?Sized> NonNull<T> {
     #[rustc_const_unstable(feature = "const_ptr_sub_ptr", issue = "95892")]
     pub const unsafe fn byte_sub_ptr<U: ?Sized>(self, origin: NonNull<U>) -> usize {
         // SAFETY: the caller must uphold the safety contract for `byte_sub_ptr`.
-        unsafe { self.pointer.byte_sub_ptr(origin.pointer) }
+        unsafe { self.as_ptr().byte_sub_ptr(origin.as_ptr()) }
     }
 
     /// Reads the value from `self` without moving it. This leaves the
@@ -893,7 +900,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `read`.
-        unsafe { ptr::read(self.pointer) }
+        unsafe { ptr::read(self.as_ptr()) }
     }
 
     /// Performs a volatile read of the value from `self` without moving it. This
@@ -914,7 +921,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `read_volatile`.
-        unsafe { ptr::read_volatile(self.pointer) }
+        unsafe { ptr::read_volatile(self.as_ptr()) }
     }
 
     /// Reads the value from `self` without moving it. This leaves the
@@ -934,7 +941,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `read_unaligned`.
-        unsafe { ptr::read_unaligned(self.pointer) }
+        unsafe { ptr::read_unaligned(self.as_ptr()) }
     }
 
     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -954,7 +961,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `copy`.
-        unsafe { ptr::copy(self.pointer, dest.as_ptr(), count) }
+        unsafe { ptr::copy(self.as_ptr(), dest.as_ptr(), count) }
     }
 
     /// Copies `count * size_of<T>` bytes from `self` to `dest`. The source
@@ -974,7 +981,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
-        unsafe { ptr::copy_nonoverlapping(self.pointer, dest.as_ptr(), count) }
+        unsafe { ptr::copy_nonoverlapping(self.as_ptr(), dest.as_ptr(), count) }
     }
 
     /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -994,7 +1001,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `copy`.
-        unsafe { ptr::copy(src.pointer, self.as_ptr(), count) }
+        unsafe { ptr::copy(src.as_ptr(), self.as_ptr(), count) }
     }
 
     /// Copies `count * size_of<T>` bytes from `src` to `self`. The source
@@ -1014,7 +1021,7 @@ impl<T: ?Sized> NonNull<T> {
         T: Sized,
     {
         // SAFETY: the caller must uphold the safety contract for `copy_nonoverlapping`.
-        unsafe { ptr::copy_nonoverlapping(src.pointer, self.as_ptr(), count) }
+        unsafe { ptr::copy_nonoverlapping(src.as_ptr(), self.as_ptr(), count) }
     }
 
     /// Executes the destructor (if any) of the pointed-to value.
@@ -1201,7 +1208,7 @@ impl<T: ?Sized> NonNull<T> {
 
         {
             // SAFETY: `align` has been checked to be a power of 2 above.
-            unsafe { ptr::align_offset(self.pointer, align) }
+            unsafe { ptr::align_offset(self.as_ptr(), align) }
         }
     }
 
@@ -1229,7 +1236,7 @@ impl<T: ?Sized> NonNull<T> {
     where
         T: Sized,
     {
-        self.pointer.is_aligned()
+        self.as_ptr().is_aligned()
     }
 
     /// Returns whether the pointer is aligned to `align`.
@@ -1266,7 +1273,7 @@ impl<T: ?Sized> NonNull<T> {
     #[must_use]
     #[unstable(feature = "pointer_is_aligned_to", issue = "96284")]
     pub fn is_aligned_to(self, align: usize) -> bool {
-        self.pointer.is_aligned_to(align)
+        self.as_ptr().is_aligned_to(align)
     }
 }
 
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
index 87fbcca9177..027c71dfaae 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-abort.diff
@@ -31,7 +31,6 @@
               }
           }
           scope 9 (inlined NonNull::<[u8]>::as_ptr) {
-              let mut _17: *const [u8];
           }
       }
       scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@@ -102,16 +101,9 @@
           StorageDead(_16);
           StorageDead(_12);
           StorageDead(_6);
--         StorageLive(_17);
-+         nop;
-          _17 = copy (_5.0: *const [u8]);
--         _4 = move _17 as *mut [u8] (PtrToPtr);
--         StorageDead(_17);
-+         _4 = copy _17 as *mut [u8] (PtrToPtr);
-+         nop;
+          _4 = copy _5 as *mut [u8] (Transmute);
           StorageDead(_5);
--         _3 = move _4 as *mut u8 (PtrToPtr);
-+         _3 = copy _17 as *mut u8 (PtrToPtr);
+          _3 = move _4 as *mut u8 (PtrToPtr);
           StorageDead(_4);
           StorageDead(_3);
 -         StorageDead(_1);
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
index 5fcece2280d..88bd4628c29 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.32bit.panic-unwind.diff
@@ -20,7 +20,6 @@
           scope 5 (inlined <std::alloc::Global as Allocator>::allocate) {
           }
           scope 6 (inlined NonNull::<[u8]>::as_ptr) {
-              let mut _12: *const [u8];
           }
       }
       scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@@ -45,16 +44,9 @@
   
       bb1: {
           StorageDead(_6);
--         StorageLive(_12);
-+         nop;
-          _12 = copy (_5.0: *const [u8]);
--         _4 = move _12 as *mut [u8] (PtrToPtr);
--         StorageDead(_12);
-+         _4 = copy _12 as *mut [u8] (PtrToPtr);
-+         nop;
+          _4 = copy _5 as *mut [u8] (Transmute);
           StorageDead(_5);
--         _3 = move _4 as *mut u8 (PtrToPtr);
-+         _3 = copy _12 as *mut u8 (PtrToPtr);
+          _3 = move _4 as *mut u8 (PtrToPtr);
           StorageDead(_4);
           StorageDead(_3);
 -         StorageDead(_1);
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
index 13258c17160..ebf305a6f1b 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-abort.diff
@@ -31,7 +31,6 @@
               }
           }
           scope 9 (inlined NonNull::<[u8]>::as_ptr) {
-              let mut _17: *const [u8];
           }
       }
       scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@@ -102,16 +101,9 @@
           StorageDead(_16);
           StorageDead(_12);
           StorageDead(_6);
--         StorageLive(_17);
-+         nop;
-          _17 = copy (_5.0: *const [u8]);
--         _4 = move _17 as *mut [u8] (PtrToPtr);
--         StorageDead(_17);
-+         _4 = copy _17 as *mut [u8] (PtrToPtr);
-+         nop;
+          _4 = copy _5 as *mut [u8] (Transmute);
           StorageDead(_5);
--         _3 = move _4 as *mut u8 (PtrToPtr);
-+         _3 = copy _17 as *mut u8 (PtrToPtr);
+          _3 = move _4 as *mut u8 (PtrToPtr);
           StorageDead(_4);
           StorageDead(_3);
 -         StorageDead(_1);
diff --git a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
index 0821ea272bf..0c52f1e0583 100644
--- a/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
+++ b/tests/mir-opt/pre-codegen/issue_117368_print_invalid_constant.main.GVN.64bit.panic-unwind.diff
@@ -20,7 +20,6 @@
           scope 5 (inlined <std::alloc::Global as Allocator>::allocate) {
           }
           scope 6 (inlined NonNull::<[u8]>::as_ptr) {
-              let mut _12: *const [u8];
           }
       }
       scope 3 (inlined #[track_caller] Option::<Layout>::unwrap) {
@@ -45,16 +44,9 @@
   
       bb1: {
           StorageDead(_6);
--         StorageLive(_12);
-+         nop;
-          _12 = copy (_5.0: *const [u8]);
--         _4 = move _12 as *mut [u8] (PtrToPtr);
--         StorageDead(_12);
-+         _4 = copy _12 as *mut [u8] (PtrToPtr);
-+         nop;
+          _4 = copy _5 as *mut [u8] (Transmute);
           StorageDead(_5);
--         _3 = move _4 as *mut u8 (PtrToPtr);
-+         _3 = copy _12 as *mut u8 (PtrToPtr);
+          _3 = move _4 as *mut u8 (PtrToPtr);
           StorageDead(_4);
           StorageDead(_3);
 -         StorageDead(_1);
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
index bd56ab67e00..a3308cc5df1 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-abort.mir
@@ -4,28 +4,28 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _11: std::slice::Iter<'_, T>;
-    let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _21: std::option::Option<(usize, &T)>;
-    let mut _24: &impl Fn(usize, &T);
-    let mut _25: (usize, &T);
-    let _26: ();
+    let mut _13: std::slice::Iter<'_, T>;
+    let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _23: std::option::Option<(usize, &T)>;
+    let mut _26: &impl Fn(usize, &T);
+    let mut _27: (usize, &T);
+    let _28: ();
     scope 1 {
-        debug iter => _13;
-        let _22: usize;
-        let _23: &T;
+        debug iter => _15;
+        let _24: usize;
+        let _25: &T;
         scope 2 {
-            debug i => _22;
-            debug x => _23;
+            debug i => _24;
+            debug x => _25;
         }
         scope 18 (inlined <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next) {
-            let mut _14: &mut std::slice::Iter<'_, T>;
-            let mut _15: std::option::Option<&T>;
-            let mut _19: (usize, bool);
-            let mut _20: (usize, &T);
+            let mut _16: &mut std::slice::Iter<'_, T>;
+            let mut _17: std::option::Option<&T>;
+            let mut _21: (usize, bool);
+            let mut _22: (usize, &T);
             scope 19 {
-                let _18: usize;
+                let _20: usize;
                 scope 24 {
                 }
             }
@@ -40,8 +40,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                 }
             }
             scope 25 (inlined <Option<&T> as Try>::branch) {
-                let mut _16: isize;
-                let _17: &T;
+                let mut _18: isize;
+                let _19: &T;
                 scope 26 {
                 }
             }
@@ -50,13 +50,14 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _7: *mut T;
-            let mut _8: *mut T;
-            let mut _10: *const T;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _9: *mut T;
+            let mut _10: *mut T;
+            let mut _12: *const T;
             scope 5 {
-                let _6: std::ptr::NonNull<T>;
+                let _8: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _9: *const T;
+                    let _11: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -72,7 +73,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _5: *const T;
+                    let mut _6: *mut [T];
+                    let mut _7: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -87,76 +89,82 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb0: {
-        StorageLive(_11);
+        StorageLive(_13);
         StorageLive(_3);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_5);
+        StorageLive(_8);
         _3 = PtrMetadata(copy _1);
+        StorageLive(_5);
+        StorageLive(_4);
         _4 = &raw const (*_1);
-        _5 = copy _4 as *const T (PtrToPtr);
-        _6 = NonNull::<T> { pointer: copy _5 };
-        StorageLive(_9);
+        _5 = NonNull::<[T]> { pointer: move _4 };
+        StorageDead(_4);
+        StorageLive(_6);
+        StorageLive(_7);
+        _6 = copy _5 as *mut [T] (Transmute);
+        _7 = copy _6 as *const T (PtrToPtr);
+        _8 = NonNull::<T> { pointer: move _7 };
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageLive(_11);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_8);
-        StorageLive(_7);
-        _7 = copy _4 as *mut T (PtrToPtr);
-        _8 = Offset(copy _7, copy _3);
-        StorageDead(_7);
-        _9 = move _8 as *const T (PtrToPtr);
-        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_9);
+        _9 = copy _8 as *mut T (Transmute);
+        _10 = Offset(copy _9, copy _3);
+        StorageDead(_9);
+        _11 = move _10 as *const T (PtrToPtr);
+        StorageDead(_10);
         goto -> bb3;
     }
 
     bb2: {
-        _9 = copy _3 as *const T (Transmute);
+        _11 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_10);
-        _10 = copy _9;
-        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_10);
-        StorageDead(_9);
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_6);
-        StorageDead(_3);
-        _12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
+        StorageLive(_12);
+        _12 = copy _11;
+        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_12);
         StorageDead(_11);
-        StorageLive(_13);
-        _13 = copy _12;
+        StorageDead(_8);
+        StorageDead(_3);
+        _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
+        StorageDead(_13);
+        StorageLive(_15);
+        _15 = copy _14;
         goto -> bb4;
     }
 
     bb4: {
+        StorageLive(_23);
+        StorageLive(_20);
         StorageLive(_21);
-        StorageLive(_18);
-        StorageLive(_19);
-        StorageLive(_15);
-        StorageLive(_14);
-        _14 = &mut (_13.0: std::slice::Iter<'_, T>);
-        _15 = <std::slice::Iter<'_, T> as Iterator>::next(move _14) -> [return: bb5, unwind unreachable];
+        StorageLive(_17);
+        StorageLive(_16);
+        _16 = &mut (_15.0: std::slice::Iter<'_, T>);
+        _17 = <std::slice::Iter<'_, T> as Iterator>::next(move _16) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        StorageDead(_14);
-        StorageLive(_16);
-        _16 = discriminant(_15);
-        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb11];
+        StorageDead(_16);
+        StorageLive(_18);
+        _18 = discriminant(_17);
+        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb11];
     }
 
     bb6: {
-        StorageDead(_16);
-        StorageDead(_15);
-        StorageDead(_19);
         StorageDead(_18);
+        StorageDead(_17);
         StorageDead(_21);
-        StorageDead(_13);
+        StorageDead(_20);
+        StorageDead(_23);
+        StorageDead(_15);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -165,35 +173,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb8: {
-        _17 = move ((_15 as Some).0: &T);
-        StorageDead(_16);
-        StorageDead(_15);
-        _18 = copy (_13.1: usize);
-        _19 = AddWithOverflow(copy (_13.1: usize), const 1_usize);
-        assert(!move (_19.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_13.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
+        _19 = move ((_17 as Some).0: &T);
+        StorageDead(_18);
+        StorageDead(_17);
+        _20 = copy (_15.1: usize);
+        _21 = AddWithOverflow(copy (_15.1: usize), const 1_usize);
+        assert(!move (_21.1: bool), "attempt to compute `{} + {}`, which would overflow", copy (_15.1: usize), const 1_usize) -> [success: bb9, unwind unreachable];
     }
 
     bb9: {
-        (_13.1: usize) = move (_19.0: usize);
-        StorageLive(_20);
-        _20 = (copy _18, copy _17);
-        _21 = Option::<(usize, &T)>::Some(move _20);
+        (_15.1: usize) = move (_21.0: usize);
+        StorageLive(_22);
+        _22 = (copy _20, copy _19);
+        _23 = Option::<(usize, &T)>::Some(move _22);
+        StorageDead(_22);
+        StorageDead(_21);
         StorageDead(_20);
-        StorageDead(_19);
-        StorageDead(_18);
-        _22 = copy (((_21 as Some).0: (usize, &T)).0: usize);
-        _23 = copy (((_21 as Some).0: (usize, &T)).1: &T);
-        StorageLive(_24);
-        _24 = &_2;
-        StorageLive(_25);
-        _25 = (copy _22, copy _23);
-        _26 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _24, move _25) -> [return: bb10, unwind unreachable];
+        _24 = copy (((_23 as Some).0: (usize, &T)).0: usize);
+        _25 = copy (((_23 as Some).0: (usize, &T)).1: &T);
+        StorageLive(_26);
+        _26 = &_2;
+        StorageLive(_27);
+        _27 = (copy _24, copy _25);
+        _28 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _26, move _27) -> [return: bb10, unwind unreachable];
     }
 
     bb10: {
-        StorageDead(_25);
-        StorageDead(_24);
-        StorageDead(_21);
+        StorageDead(_27);
+        StorageDead(_26);
+        StorageDead(_23);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
index 57f09a4631b..2a837fabd4c 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir
@@ -4,34 +4,35 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _11: std::slice::Iter<'_, T>;
-    let mut _12: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _13: std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _14: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
-    let mut _15: std::option::Option<(usize, &T)>;
-    let mut _16: isize;
-    let mut _19: &impl Fn(usize, &T);
-    let mut _20: (usize, &T);
-    let _21: ();
+    let mut _13: std::slice::Iter<'_, T>;
+    let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
+    let mut _17: std::option::Option<(usize, &T)>;
+    let mut _18: isize;
+    let mut _21: &impl Fn(usize, &T);
+    let mut _22: (usize, &T);
+    let _23: ();
     scope 1 {
-        debug iter => _13;
-        let _17: usize;
-        let _18: &T;
+        debug iter => _15;
+        let _19: usize;
+        let _20: &T;
         scope 2 {
-            debug i => _17;
-            debug x => _18;
+            debug i => _19;
+            debug x => _20;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _7: *mut T;
-            let mut _8: *mut T;
-            let mut _10: *const T;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _9: *mut T;
+            let mut _10: *mut T;
+            let mut _12: *const T;
             scope 5 {
-                let _6: std::ptr::NonNull<T>;
+                let _8: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _9: *const T;
+                    let _11: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -47,7 +48,8 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _5: *const T;
+                    let mut _6: *mut [T];
+                    let mut _7: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -62,66 +64,72 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb0: {
-        StorageLive(_11);
+        StorageLive(_13);
         StorageLive(_3);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_5);
+        StorageLive(_8);
         _3 = PtrMetadata(copy _1);
+        StorageLive(_5);
+        StorageLive(_4);
         _4 = &raw const (*_1);
-        _5 = copy _4 as *const T (PtrToPtr);
-        _6 = NonNull::<T> { pointer: copy _5 };
-        StorageLive(_9);
+        _5 = NonNull::<[T]> { pointer: move _4 };
+        StorageDead(_4);
+        StorageLive(_6);
+        StorageLive(_7);
+        _6 = copy _5 as *mut [T] (Transmute);
+        _7 = copy _6 as *const T (PtrToPtr);
+        _8 = NonNull::<T> { pointer: move _7 };
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageLive(_11);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_8);
-        StorageLive(_7);
-        _7 = copy _4 as *mut T (PtrToPtr);
-        _8 = Offset(copy _7, copy _3);
-        StorageDead(_7);
-        _9 = move _8 as *const T (PtrToPtr);
-        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_9);
+        _9 = copy _8 as *mut T (Transmute);
+        _10 = Offset(copy _9, copy _3);
+        StorageDead(_9);
+        _11 = move _10 as *const T (PtrToPtr);
+        StorageDead(_10);
         goto -> bb3;
     }
 
     bb2: {
-        _9 = copy _3 as *const T (Transmute);
+        _11 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_10);
-        _10 = copy _9;
-        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_10);
-        StorageDead(_9);
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_6);
-        StorageDead(_3);
-        _12 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _11, count: const 0_usize };
+        StorageLive(_12);
+        _12 = copy _11;
+        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_12);
         StorageDead(_11);
-        StorageLive(_13);
-        _13 = copy _12;
+        StorageDead(_8);
+        StorageDead(_3);
+        _14 = Enumerate::<std::slice::Iter<'_, T>> { iter: copy _13, count: const 0_usize };
+        StorageDead(_13);
+        StorageLive(_15);
+        _15 = copy _14;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_15);
-        _14 = &mut _13;
-        _15 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _14) -> [return: bb5, unwind: bb11];
+        StorageLive(_17);
+        _16 = &mut _15;
+        _17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        _16 = discriminant(_15);
-        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
+        _18 = discriminant(_17);
+        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_17);
         StorageDead(_15);
-        StorageDead(_13);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -130,19 +138,19 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
     }
 
     bb8: {
-        _17 = copy (((_15 as Some).0: (usize, &T)).0: usize);
-        _18 = copy (((_15 as Some).0: (usize, &T)).1: &T);
-        StorageLive(_19);
-        _19 = &_2;
-        StorageLive(_20);
-        _20 = (copy _17, copy _18);
-        _21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
+        _19 = copy (((_17 as Some).0: (usize, &T)).0: usize);
+        _20 = copy (((_17 as Some).0: (usize, &T)).1: &T);
+        StorageLive(_21);
+        _21 = &_2;
+        StorageLive(_22);
+        _22 = (copy _19, copy _20);
+        _23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_20);
-        StorageDead(_19);
-        StorageDead(_15);
+        StorageDead(_22);
+        StorageDead(_21);
+        StorageDead(_17);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
index 4050304f469..063045caebb 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-abort.mir
@@ -4,31 +4,32 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _11: std::slice::Iter<'_, T>;
-    let mut _12: std::slice::Iter<'_, T>;
-    let mut _13: &mut std::slice::Iter<'_, T>;
-    let mut _14: std::option::Option<&T>;
-    let mut _15: isize;
-    let mut _17: &impl Fn(&T);
-    let mut _18: (&T,);
-    let _19: ();
+    let mut _13: std::slice::Iter<'_, T>;
+    let mut _14: std::slice::Iter<'_, T>;
+    let mut _15: &mut std::slice::Iter<'_, T>;
+    let mut _16: std::option::Option<&T>;
+    let mut _17: isize;
+    let mut _19: &impl Fn(&T);
+    let mut _20: (&T,);
+    let _21: ();
     scope 1 {
-        debug iter => _12;
-        let _16: &T;
+        debug iter => _14;
+        let _18: &T;
         scope 2 {
-            debug x => _16;
+            debug x => _18;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _7: *mut T;
-            let mut _8: *mut T;
-            let mut _10: *const T;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _9: *mut T;
+            let mut _10: *mut T;
+            let mut _12: *const T;
             scope 5 {
-                let _6: std::ptr::NonNull<T>;
+                let _8: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _9: *const T;
+                    let _11: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _5: *const T;
+                    let mut _6: *mut [T];
+                    let mut _7: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
 
     bb0: {
         StorageLive(_3);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_5);
+        StorageLive(_8);
         _3 = PtrMetadata(copy _1);
+        StorageLive(_5);
+        StorageLive(_4);
         _4 = &raw const (*_1);
-        _5 = copy _4 as *const T (PtrToPtr);
-        _6 = NonNull::<T> { pointer: copy _5 };
-        StorageLive(_9);
+        _5 = NonNull::<[T]> { pointer: move _4 };
+        StorageDead(_4);
+        StorageLive(_6);
+        StorageLive(_7);
+        _6 = copy _5 as *mut [T] (Transmute);
+        _7 = copy _6 as *const T (PtrToPtr);
+        _8 = NonNull::<T> { pointer: move _7 };
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageLive(_11);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_8);
-        StorageLive(_7);
-        _7 = copy _4 as *mut T (PtrToPtr);
-        _8 = Offset(copy _7, copy _3);
-        StorageDead(_7);
-        _9 = move _8 as *const T (PtrToPtr);
-        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_9);
+        _9 = copy _8 as *mut T (Transmute);
+        _10 = Offset(copy _9, copy _3);
+        StorageDead(_9);
+        _11 = move _10 as *const T (PtrToPtr);
+        StorageDead(_10);
         goto -> bb3;
     }
 
     bb2: {
-        _9 = copy _3 as *const T (Transmute);
+        _11 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_10);
-        _10 = copy _9;
-        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_10);
-        StorageDead(_9);
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_6);
-        StorageDead(_3);
         StorageLive(_12);
         _12 = copy _11;
+        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_12);
+        StorageDead(_11);
+        StorageDead(_8);
+        StorageDead(_3);
+        StorageLive(_14);
+        _14 = copy _13;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_14);
-        _13 = &mut _12;
-        _14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind unreachable];
+        StorageLive(_16);
+        _15 = &mut _14;
+        _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        _15 = discriminant(_14);
-        switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
+        _17 = discriminant(_16);
+        switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_16);
         StorageDead(_14);
-        StorageDead(_12);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _16 = copy ((_14 as Some).0: &T);
-        StorageLive(_17);
-        _17 = &_2;
-        StorageLive(_18);
-        _18 = (copy _16,);
-        _19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind unreachable];
+        _18 = copy ((_16 as Some).0: &T);
+        StorageLive(_19);
+        _19 = &_2;
+        StorageLive(_20);
+        _20 = (copy _18,);
+        _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind unreachable];
     }
 
     bb9: {
-        StorageDead(_18);
-        StorageDead(_17);
-        StorageDead(_14);
+        StorageDead(_20);
+        StorageDead(_19);
+        StorageDead(_16);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
index 2c3d7ab1e4a..d401ed8fcf3 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir
@@ -4,31 +4,32 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _11: std::slice::Iter<'_, T>;
-    let mut _12: std::slice::Iter<'_, T>;
-    let mut _13: &mut std::slice::Iter<'_, T>;
-    let mut _14: std::option::Option<&T>;
-    let mut _15: isize;
-    let mut _17: &impl Fn(&T);
-    let mut _18: (&T,);
-    let _19: ();
+    let mut _13: std::slice::Iter<'_, T>;
+    let mut _14: std::slice::Iter<'_, T>;
+    let mut _15: &mut std::slice::Iter<'_, T>;
+    let mut _16: std::option::Option<&T>;
+    let mut _17: isize;
+    let mut _19: &impl Fn(&T);
+    let mut _20: (&T,);
+    let _21: ();
     scope 1 {
-        debug iter => _12;
-        let _16: &T;
+        debug iter => _14;
+        let _18: &T;
         scope 2 {
-            debug x => _16;
+            debug x => _18;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _7: *mut T;
-            let mut _8: *mut T;
-            let mut _10: *const T;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _9: *mut T;
+            let mut _10: *mut T;
+            let mut _12: *const T;
             scope 5 {
-                let _6: std::ptr::NonNull<T>;
+                let _8: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _9: *const T;
+                    let _11: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -44,7 +45,8 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _5: *const T;
+                    let mut _6: *mut [T];
+                    let mut _7: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -56,62 +58,68 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
 
     bb0: {
         StorageLive(_3);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_5);
+        StorageLive(_8);
         _3 = PtrMetadata(copy _1);
+        StorageLive(_5);
+        StorageLive(_4);
         _4 = &raw const (*_1);
-        _5 = copy _4 as *const T (PtrToPtr);
-        _6 = NonNull::<T> { pointer: copy _5 };
-        StorageLive(_9);
+        _5 = NonNull::<[T]> { pointer: move _4 };
+        StorageDead(_4);
+        StorageLive(_6);
+        StorageLive(_7);
+        _6 = copy _5 as *mut [T] (Transmute);
+        _7 = copy _6 as *const T (PtrToPtr);
+        _8 = NonNull::<T> { pointer: move _7 };
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageLive(_11);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_8);
-        StorageLive(_7);
-        _7 = copy _4 as *mut T (PtrToPtr);
-        _8 = Offset(copy _7, copy _3);
-        StorageDead(_7);
-        _9 = move _8 as *const T (PtrToPtr);
-        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_9);
+        _9 = copy _8 as *mut T (Transmute);
+        _10 = Offset(copy _9, copy _3);
+        StorageDead(_9);
+        _11 = move _10 as *const T (PtrToPtr);
+        StorageDead(_10);
         goto -> bb3;
     }
 
     bb2: {
-        _9 = copy _3 as *const T (Transmute);
+        _11 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_10);
-        _10 = copy _9;
-        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_10);
-        StorageDead(_9);
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_6);
-        StorageDead(_3);
         StorageLive(_12);
         _12 = copy _11;
+        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_12);
+        StorageDead(_11);
+        StorageDead(_8);
+        StorageDead(_3);
+        StorageLive(_14);
+        _14 = copy _13;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_14);
-        _13 = &mut _12;
-        _14 = <std::slice::Iter<'_, T> as Iterator>::next(move _13) -> [return: bb5, unwind: bb11];
+        StorageLive(_16);
+        _15 = &mut _14;
+        _16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        _15 = discriminant(_14);
-        switchInt(move _15) -> [0: bb6, 1: bb8, otherwise: bb10];
+        _17 = discriminant(_16);
+        switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_16);
         StorageDead(_14);
-        StorageDead(_12);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -120,18 +128,18 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _16 = copy ((_14 as Some).0: &T);
-        StorageLive(_17);
-        _17 = &_2;
-        StorageLive(_18);
-        _18 = (copy _16,);
-        _19 = <impl Fn(&T) as Fn<(&T,)>>::call(move _17, move _18) -> [return: bb9, unwind: bb11];
+        _18 = copy ((_16 as Some).0: &T);
+        StorageLive(_19);
+        _19 = &_2;
+        StorageLive(_20);
+        _20 = (copy _18,);
+        _21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_18);
-        StorageDead(_17);
-        StorageDead(_14);
+        StorageDead(_20);
+        StorageDead(_19);
+        StorageDead(_16);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
index a6ccd435c40..deb12c4f1c2 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-abort.mir
@@ -4,34 +4,35 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _11: std::slice::Iter<'_, T>;
-    let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _15: std::option::Option<&T>;
-    let mut _16: isize;
-    let mut _18: &impl Fn(&T);
-    let mut _19: (&T,);
-    let _20: ();
+    let mut _13: std::slice::Iter<'_, T>;
+    let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _17: std::option::Option<&T>;
+    let mut _18: isize;
+    let mut _20: &impl Fn(&T);
+    let mut _21: (&T,);
+    let _22: ();
     scope 1 {
-        debug iter => _13;
-        let _17: &T;
+        debug iter => _15;
+        let _19: &T;
         scope 2 {
-            debug x => _17;
+            debug x => _19;
         }
         scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
-            let mut _14: &mut std::slice::Iter<'_, T>;
+            let mut _16: &mut std::slice::Iter<'_, T>;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _7: *mut T;
-            let mut _8: *mut T;
-            let mut _10: *const T;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _9: *mut T;
+            let mut _10: *mut T;
+            let mut _12: *const T;
             scope 5 {
-                let _6: std::ptr::NonNull<T>;
+                let _8: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _9: *const T;
+                    let _11: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _5: *const T;
+                    let mut _6: *mut [T];
+                    let mut _7: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb0: {
-        StorageLive(_11);
+        StorageLive(_13);
         StorageLive(_3);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_5);
+        StorageLive(_8);
         _3 = PtrMetadata(copy _1);
+        StorageLive(_5);
+        StorageLive(_4);
         _4 = &raw const (*_1);
-        _5 = copy _4 as *const T (PtrToPtr);
-        _6 = NonNull::<T> { pointer: copy _5 };
-        StorageLive(_9);
+        _5 = NonNull::<[T]> { pointer: move _4 };
+        StorageDead(_4);
+        StorageLive(_6);
+        StorageLive(_7);
+        _6 = copy _5 as *mut [T] (Transmute);
+        _7 = copy _6 as *const T (PtrToPtr);
+        _8 = NonNull::<T> { pointer: move _7 };
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageLive(_11);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_8);
-        StorageLive(_7);
-        _7 = copy _4 as *mut T (PtrToPtr);
-        _8 = Offset(copy _7, copy _3);
-        StorageDead(_7);
-        _9 = move _8 as *const T (PtrToPtr);
-        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_9);
+        _9 = copy _8 as *mut T (Transmute);
+        _10 = Offset(copy _9, copy _3);
+        StorageDead(_9);
+        _11 = move _10 as *const T (PtrToPtr);
+        StorageDead(_10);
         goto -> bb3;
     }
 
     bb2: {
-        _9 = copy _3 as *const T (Transmute);
+        _11 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_10);
-        _10 = copy _9;
-        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_10);
-        StorageDead(_9);
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_6);
-        StorageDead(_3);
-        _12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
+        StorageLive(_12);
+        _12 = copy _11;
+        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_12);
         StorageDead(_11);
-        StorageLive(_13);
-        _13 = copy _12;
+        StorageDead(_8);
+        StorageDead(_3);
+        _14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
+        StorageDead(_13);
+        StorageLive(_15);
+        _15 = copy _14;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_15);
-        StorageLive(_14);
-        _14 = &mut (_13.0: std::slice::Iter<'_, T>);
-        _15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind unreachable];
+        StorageLive(_17);
+        StorageLive(_16);
+        _16 = &mut (_15.0: std::slice::Iter<'_, T>);
+        _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind unreachable];
     }
 
     bb5: {
-        StorageDead(_14);
-        _16 = discriminant(_15);
-        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_16);
+        _18 = discriminant(_17);
+        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_17);
         StorageDead(_15);
-        StorageDead(_13);
         drop(_2) -> [return: bb7, unwind unreachable];
     }
 
@@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _17 = copy ((_15 as Some).0: &T);
-        StorageLive(_18);
-        _18 = &_2;
-        StorageLive(_19);
-        _19 = (copy _17,);
-        _20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind unreachable];
+        _19 = copy ((_17 as Some).0: &T);
+        StorageLive(_20);
+        _20 = &_2;
+        StorageLive(_21);
+        _21 = (copy _19,);
+        _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind unreachable];
     }
 
     bb9: {
-        StorageDead(_19);
-        StorageDead(_18);
-        StorageDead(_15);
+        StorageDead(_21);
+        StorageDead(_20);
+        StorageDead(_17);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
index df11c8e3b49..acd5323eb7a 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir
@@ -4,34 +4,35 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     debug slice => _1;
     debug f => _2;
     let mut _0: ();
-    let mut _11: std::slice::Iter<'_, T>;
-    let mut _12: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _13: std::iter::Rev<std::slice::Iter<'_, T>>;
-    let mut _15: std::option::Option<&T>;
-    let mut _16: isize;
-    let mut _18: &impl Fn(&T);
-    let mut _19: (&T,);
-    let _20: ();
+    let mut _13: std::slice::Iter<'_, T>;
+    let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
+    let mut _17: std::option::Option<&T>;
+    let mut _18: isize;
+    let mut _20: &impl Fn(&T);
+    let mut _21: (&T,);
+    let _22: ();
     scope 1 {
-        debug iter => _13;
-        let _17: &T;
+        debug iter => _15;
+        let _19: &T;
         scope 2 {
-            debug x => _17;
+            debug x => _19;
         }
         scope 18 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
-            let mut _14: &mut std::slice::Iter<'_, T>;
+            let mut _16: &mut std::slice::Iter<'_, T>;
         }
     }
     scope 3 (inlined core::slice::<impl [T]>::iter) {
         scope 4 (inlined std::slice::Iter::<'_, T>::new) {
             let _3: usize;
-            let mut _7: *mut T;
-            let mut _8: *mut T;
-            let mut _10: *const T;
+            let mut _5: std::ptr::NonNull<[T]>;
+            let mut _9: *mut T;
+            let mut _10: *mut T;
+            let mut _12: *const T;
             scope 5 {
-                let _6: std::ptr::NonNull<T>;
+                let _8: std::ptr::NonNull<T>;
                 scope 6 {
-                    let _9: *const T;
+                    let _11: *const T;
                     scope 7 {
                     }
                     scope 12 (inlined without_provenance::<T>) {
@@ -47,7 +48,8 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
                     }
                 }
                 scope 10 (inlined NonNull::<[T]>::cast::<T>) {
-                    let mut _5: *const T;
+                    let mut _6: *mut [T];
+                    let mut _7: *const T;
                     scope 11 (inlined NonNull::<[T]>::as_ptr) {
                     }
                 }
@@ -62,68 +64,74 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb0: {
-        StorageLive(_11);
+        StorageLive(_13);
         StorageLive(_3);
-        StorageLive(_6);
-        StorageLive(_4);
-        StorageLive(_5);
+        StorageLive(_8);
         _3 = PtrMetadata(copy _1);
+        StorageLive(_5);
+        StorageLive(_4);
         _4 = &raw const (*_1);
-        _5 = copy _4 as *const T (PtrToPtr);
-        _6 = NonNull::<T> { pointer: copy _5 };
-        StorageLive(_9);
+        _5 = NonNull::<[T]> { pointer: move _4 };
+        StorageDead(_4);
+        StorageLive(_6);
+        StorageLive(_7);
+        _6 = copy _5 as *mut [T] (Transmute);
+        _7 = copy _6 as *const T (PtrToPtr);
+        _8 = NonNull::<T> { pointer: move _7 };
+        StorageDead(_7);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageLive(_11);
         switchInt(const <T as std::mem::SizedTypeProperties>::IS_ZST) -> [0: bb1, otherwise: bb2];
     }
 
     bb1: {
-        StorageLive(_8);
-        StorageLive(_7);
-        _7 = copy _4 as *mut T (PtrToPtr);
-        _8 = Offset(copy _7, copy _3);
-        StorageDead(_7);
-        _9 = move _8 as *const T (PtrToPtr);
-        StorageDead(_8);
+        StorageLive(_10);
+        StorageLive(_9);
+        _9 = copy _8 as *mut T (Transmute);
+        _10 = Offset(copy _9, copy _3);
+        StorageDead(_9);
+        _11 = move _10 as *const T (PtrToPtr);
+        StorageDead(_10);
         goto -> bb3;
     }
 
     bb2: {
-        _9 = copy _3 as *const T (Transmute);
+        _11 = copy _3 as *const T (Transmute);
         goto -> bb3;
     }
 
     bb3: {
-        StorageLive(_10);
-        _10 = copy _9;
-        _11 = std::slice::Iter::<'_, T> { ptr: copy _6, end_or_len: move _10, _marker: const ZeroSized: PhantomData<&T> };
-        StorageDead(_10);
-        StorageDead(_9);
-        StorageDead(_5);
-        StorageDead(_4);
-        StorageDead(_6);
-        StorageDead(_3);
-        _12 = Rev::<std::slice::Iter<'_, T>> { iter: copy _11 };
+        StorageLive(_12);
+        _12 = copy _11;
+        _13 = std::slice::Iter::<'_, T> { ptr: copy _8, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
+        StorageDead(_12);
         StorageDead(_11);
-        StorageLive(_13);
-        _13 = copy _12;
+        StorageDead(_8);
+        StorageDead(_3);
+        _14 = Rev::<std::slice::Iter<'_, T>> { iter: copy _13 };
+        StorageDead(_13);
+        StorageLive(_15);
+        _15 = copy _14;
         goto -> bb4;
     }
 
     bb4: {
-        StorageLive(_15);
-        StorageLive(_14);
-        _14 = &mut (_13.0: std::slice::Iter<'_, T>);
-        _15 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _14) -> [return: bb5, unwind: bb11];
+        StorageLive(_17);
+        StorageLive(_16);
+        _16 = &mut (_15.0: std::slice::Iter<'_, T>);
+        _17 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _16) -> [return: bb5, unwind: bb11];
     }
 
     bb5: {
-        StorageDead(_14);
-        _16 = discriminant(_15);
-        switchInt(move _16) -> [0: bb6, 1: bb8, otherwise: bb10];
+        StorageDead(_16);
+        _18 = discriminant(_17);
+        switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
     }
 
     bb6: {
+        StorageDead(_17);
         StorageDead(_15);
-        StorageDead(_13);
         drop(_2) -> [return: bb7, unwind continue];
     }
 
@@ -132,18 +140,18 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
     }
 
     bb8: {
-        _17 = copy ((_15 as Some).0: &T);
-        StorageLive(_18);
-        _18 = &_2;
-        StorageLive(_19);
-        _19 = (copy _17,);
-        _20 = <impl Fn(&T) as Fn<(&T,)>>::call(move _18, move _19) -> [return: bb9, unwind: bb11];
+        _19 = copy ((_17 as Some).0: &T);
+        StorageLive(_20);
+        _20 = &_2;
+        StorageLive(_21);
+        _21 = (copy _19,);
+        _22 = <impl Fn(&T) as Fn<(&T,)>>::call(move _20, move _21) -> [return: bb9, unwind: bb11];
     }
 
     bb9: {
-        StorageDead(_19);
-        StorageDead(_18);
-        StorageDead(_15);
+        StorageDead(_21);
+        StorageDead(_20);
+        StorageDead(_17);
         goto -> bb4;
     }
 
diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir
index f8b0e749bfc..22be48c47b2 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-abort.mir
@@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
             scope 4 {
                 scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
                     let mut _5: std::ptr::NonNull<T>;
+                    let mut _6: *mut T;
+                    let mut _7: *mut T;
                     scope 9 (inlined NonNull::<T>::as_ptr) {
-                        let mut _6: *const T;
                     }
                     scope 10 (inlined NonNull::<T>::as_ptr) {
-                        let mut _7: *const T;
                     }
                 }
             }
@@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
         _4 = copy (*_3);
         StorageDead(_3);
         StorageLive(_6);
-        StorageLive(_7);
         StorageLive(_5);
         _5 = copy ((*_1).0: std::ptr::NonNull<T>);
-        _6 = copy (_5.0: *const T);
+        _6 = copy _5 as *mut T (Transmute);
         StorageDead(_5);
-        _7 = copy (_4.0: *const T);
-        _0 = Eq(copy _6, copy _7);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (Transmute);
+        _0 = Eq(move _6, move _7);
         StorageDead(_7);
         StorageDead(_6);
         goto -> bb3;
diff --git a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir
index f8b0e749bfc..22be48c47b2 100644
--- a/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_iter.slice_iter_generic_is_empty.PreCodegen.after.panic-unwind.mir
@@ -15,11 +15,11 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
             scope 4 {
                 scope 8 (inlined <NonNull<T> as PartialEq>::eq) {
                     let mut _5: std::ptr::NonNull<T>;
+                    let mut _6: *mut T;
+                    let mut _7: *mut T;
                     scope 9 (inlined NonNull::<T>::as_ptr) {
-                        let mut _6: *const T;
                     }
                     scope 10 (inlined NonNull::<T>::as_ptr) {
-                        let mut _7: *const T;
                     }
                 }
             }
@@ -48,13 +48,13 @@ fn slice_iter_generic_is_empty(_1: &std::slice::Iter<'_, T>) -> bool {
         _4 = copy (*_3);
         StorageDead(_3);
         StorageLive(_6);
-        StorageLive(_7);
         StorageLive(_5);
         _5 = copy ((*_1).0: std::ptr::NonNull<T>);
-        _6 = copy (_5.0: *const T);
+        _6 = copy _5 as *mut T (Transmute);
         StorageDead(_5);
-        _7 = copy (_4.0: *const T);
-        _0 = Eq(copy _6, copy _7);
+        StorageLive(_7);
+        _7 = copy _4 as *mut T (Transmute);
+        _0 = Eq(move _6, move _7);
         StorageDead(_7);
         StorageDead(_6);
         goto -> bb3;
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 c3091bd4395..2efbb6d9904 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
@@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _7: usize;
+            let mut _9: *const u8;
+            let mut _10: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
                 let mut _2: &alloc::raw_vec::RawVec<u8>;
+                let mut _8: *mut 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 _6: std::ptr::NonNull<u8>;
+                        let mut _7: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             debug self => _3;
                             let mut _4: std::ptr::NonNull<u8>;
@@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                                 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: *mut u8;
+                                    let mut _6: *const u8;
                                     scope 9 (inlined NonNull::<u8>::as_ptr) {
                                         debug self => _4;
-                                        let mut _5: *const u8;
                                     }
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
                                 debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::as_ptr) {
-                            debug self => _6;
+                            debug self => _7;
                         }
                     }
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
-                debug data => _5;
-                debug len => _7;
-                let _8: *const [u8];
+                debug data => _9;
+                debug len => _10;
+                let _11: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 scope 16 (inlined align_of::<u8>) {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
-                    debug data => _5;
-                    debug len => _7;
+                    debug data => _9;
+                    debug len => _10;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                        debug data_pointer => _5;
-                        debug metadata => _7;
+                        debug data_pointer => _9;
+                        debug metadata => _10;
                     }
                 }
             }
@@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     }
 
     bb0: {
+        StorageLive(_8);
+        StorageLive(_9);
         StorageLive(_2);
         _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
         StorageLive(_3);
         _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
-        StorageLive(_6);
+        StorageLive(_7);
         StorageLive(_4);
         _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
-        _5 = copy (_4.0: *const u8);
-        _6 = NonNull::<u8> { pointer: copy _5 };
-        StorageDead(_4);
+        StorageLive(_5);
+        StorageLive(_6);
+        _5 = copy _4 as *mut u8 (Transmute);
+        _6 = copy _5 as *const u8 (PtrToPtr);
+        _7 = NonNull::<u8> { pointer: move _6 };
         StorageDead(_6);
+        StorageDead(_5);
+        StorageDead(_4);
+        _8 = copy _7 as *mut u8 (Transmute);
+        StorageDead(_7);
         StorageDead(_3);
+        _9 = copy _8 as *const u8 (PtrToPtr);
         StorageDead(_2);
-        StorageLive(_7);
-        _7 = copy ((*_1).1: usize);
-        StorageLive(_8);
-        _8 = *const [u8] from (copy _5, copy _7);
-        _0 = &(*_8);
+        StorageLive(_10);
+        _10 = copy ((*_1).1: usize);
+        StorageLive(_11);
+        _11 = *const [u8] from (copy _9, copy _10);
+        _0 = &(*_11);
+        StorageDead(_11);
+        StorageDead(_10);
+        StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_7);
         return;
     }
 }
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 c3091bd4395..2efbb6d9904 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
@@ -7,16 +7,18 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
         debug self => _1;
         scope 2 (inlined Vec::<u8>::as_slice) {
             debug self => _1;
-            let mut _7: usize;
+            let mut _9: *const u8;
+            let mut _10: usize;
             scope 3 (inlined Vec::<u8>::as_ptr) {
                 debug self => _1;
                 let mut _2: &alloc::raw_vec::RawVec<u8>;
+                let mut _8: *mut 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 _6: std::ptr::NonNull<u8>;
+                        let mut _7: std::ptr::NonNull<u8>;
                         scope 6 (inlined alloc::raw_vec::RawVecInner::non_null::<u8>) {
                             debug self => _3;
                             let mut _4: std::ptr::NonNull<u8>;
@@ -25,27 +27,28 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                                 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: *mut u8;
+                                    let mut _6: *const u8;
                                     scope 9 (inlined NonNull::<u8>::as_ptr) {
                                         debug self => _4;
-                                        let mut _5: *const u8;
                                     }
                                 }
                             }
                             scope 10 (inlined Unique::<u8>::as_non_null_ptr) {
-                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _6;
+                                debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _7;
                                 debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
                             }
                         }
                         scope 11 (inlined NonNull::<u8>::as_ptr) {
-                            debug self => _6;
+                            debug self => _7;
                         }
                     }
                 }
             }
             scope 12 (inlined std::slice::from_raw_parts::<'_, u8>) {
-                debug data => _5;
-                debug len => _7;
-                let _8: *const [u8];
+                debug data => _9;
+                debug len => _10;
+                let _11: *const [u8];
                 scope 13 (inlined core::ub_checks::check_language_ub) {
                     scope 14 (inlined core::ub_checks::check_language_ub::runtime) {
                     }
@@ -55,11 +58,11 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
                 scope 16 (inlined align_of::<u8>) {
                 }
                 scope 17 (inlined slice_from_raw_parts::<u8>) {
-                    debug data => _5;
-                    debug len => _7;
+                    debug data => _9;
+                    debug len => _10;
                     scope 18 (inlined std::ptr::from_raw_parts::<[u8], u8>) {
-                        debug data_pointer => _5;
-                        debug metadata => _7;
+                        debug data_pointer => _9;
+                        debug metadata => _10;
                     }
                 }
             }
@@ -67,26 +70,37 @@ fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     }
 
     bb0: {
+        StorageLive(_8);
+        StorageLive(_9);
         StorageLive(_2);
         _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
         StorageLive(_3);
         _3 = &(((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner);
-        StorageLive(_6);
+        StorageLive(_7);
         StorageLive(_4);
         _4 = copy (((((*_1).0: alloc::raw_vec::RawVec<u8>).0: alloc::raw_vec::RawVecInner).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
-        _5 = copy (_4.0: *const u8);
-        _6 = NonNull::<u8> { pointer: copy _5 };
-        StorageDead(_4);
+        StorageLive(_5);
+        StorageLive(_6);
+        _5 = copy _4 as *mut u8 (Transmute);
+        _6 = copy _5 as *const u8 (PtrToPtr);
+        _7 = NonNull::<u8> { pointer: move _6 };
         StorageDead(_6);
+        StorageDead(_5);
+        StorageDead(_4);
+        _8 = copy _7 as *mut u8 (Transmute);
+        StorageDead(_7);
         StorageDead(_3);
+        _9 = copy _8 as *const u8 (PtrToPtr);
         StorageDead(_2);
-        StorageLive(_7);
-        _7 = copy ((*_1).1: usize);
-        StorageLive(_8);
-        _8 = *const [u8] from (copy _5, copy _7);
-        _0 = &(*_8);
+        StorageLive(_10);
+        _10 = copy ((*_1).1: usize);
+        StorageLive(_11);
+        _11 = *const [u8] from (copy _9, copy _10);
+        _0 = &(*_11);
+        StorageDead(_11);
+        StorageDead(_10);
+        StorageDead(_9);
         StorageDead(_8);
-        StorageDead(_7);
         return;
     }
 }