From 2d5a226f8f5a36c10c7863026f39d9d10bd38fa4 Mon Sep 17 00:00:00 2001
From: bohan <bohan-zhang@foxmail.com>
Date: Sun, 21 Apr 2024 20:40:44 +0800
Subject: [PATCH 01/15] cleanup: unnecessary clone during lower generics args

---
 compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
index d340a08ee79..dd76862451c 100644
--- a/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
+++ b/compiler/rustc_hir_analysis/src/hir_ty_lowering/generics.rs
@@ -228,8 +228,8 @@ pub fn lower_generic_args<'tcx: 'a, 'a>(
         // Check whether this segment takes generic arguments and the user has provided any.
         let (generic_args, infer_args) = ctx.args_for_def_id(def_id);
 
-        let args_iter = generic_args.iter().flat_map(|generic_args| generic_args.args.iter());
-        let mut args_iter = args_iter.clone().peekable();
+        let mut args_iter =
+            generic_args.iter().flat_map(|generic_args| generic_args.args.iter()).peekable();
 
         // If we encounter a type or const when we expect a lifetime, we infer the lifetimes.
         // If we later encounter a lifetime, we know that the arguments were provided in the

From 6ae761cd40c7fc9a69bee946a6e96bc06ca8575f Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Mateusz=20Miku=C5=82a?= <mati865@gmail.com>
Date: Sun, 21 Apr 2024 17:41:42 +0200
Subject: [PATCH 02/15] Add gnullvm targets to manifest

---
 src/tools/build-manifest/src/main.rs | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/src/tools/build-manifest/src/main.rs b/src/tools/build-manifest/src/main.rs
index c223b9f4324..f3972346bb5 100644
--- a/src/tools/build-manifest/src/main.rs
+++ b/src/tools/build-manifest/src/main.rs
@@ -56,6 +56,7 @@ static TARGETS: &[&str] = &[
     "aarch64-apple-ios-sim",
     "aarch64-unknown-fuchsia",
     "aarch64-linux-android",
+    "aarch64-pc-windows-gnullvm",
     "aarch64-pc-windows-msvc",
     "aarch64-unknown-hermit",
     "aarch64-unknown-linux-gnu",
@@ -96,6 +97,7 @@ static TARGETS: &[&str] = &[
     "i686-apple-darwin",
     "i686-linux-android",
     "i686-pc-windows-gnu",
+    "i686-pc-windows-gnullvm",
     "i686-pc-windows-msvc",
     "i686-unknown-freebsd",
     "i686-unknown-linux-gnu",
@@ -157,6 +159,7 @@ static TARGETS: &[&str] = &[
     "x86_64-unknown-fuchsia",
     "x86_64-linux-android",
     "x86_64-pc-windows-gnu",
+    "x86_64-pc-windows-gnullvm",
     "x86_64-pc-windows-msvc",
     "x86_64-pc-solaris",
     "x86_64-unikraft-linux-musl",

From e1d12ffb6c7ed29c4d0525d2e1e7e4347d8c2372 Mon Sep 17 00:00:00 2001
From: Boxy <supbscripter@gmail.com>
Date: Sun, 21 Apr 2024 18:41:32 +0100
Subject: [PATCH 03/15] removal

---
 triagebot.toml | 1 -
 1 file changed, 1 deletion(-)

diff --git a/triagebot.toml b/triagebot.toml
index 66b8f44d688..903569bf445 100644
--- a/triagebot.toml
+++ b/triagebot.toml
@@ -851,7 +851,6 @@ compiler-team-contributors = [
     "@nnethercote",
     "@fmease",
     "@fee1-dead",
-    "@BoxyUwU",
     "@jieyouxu",
 ]
 compiler = [

From 5800dc1faa391d878077cd79ac4820055ca6c0e4 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Thu, 11 Apr 2024 17:16:28 -0700
Subject: [PATCH 04/15] New slice indexing pre-codegen MIR test

---
 tests/mir-opt/pre-codegen/slice_index.rs      |  9 +++++++++
 ...ked_range.PreCodegen.after.panic-abort.mir | 19 +++++++++++++++++++
 ...ed_range.PreCodegen.after.panic-unwind.mir | 19 +++++++++++++++++++
 3 files changed, 47 insertions(+)
 create mode 100644 tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
 create mode 100644 tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir

diff --git a/tests/mir-opt/pre-codegen/slice_index.rs b/tests/mir-opt/pre-codegen/slice_index.rs
index c9dd72d8be2..04bbbff57b3 100644
--- a/tests/mir-opt/pre-codegen/slice_index.rs
+++ b/tests/mir-opt/pre-codegen/slice_index.rs
@@ -3,6 +3,7 @@
 // EMIT_MIR_FOR_EACH_PANIC_STRATEGY
 
 #![crate_type = "lib"]
+#![feature(slice_ptr_get)]
 
 use std::ops::Range;
 
@@ -25,3 +26,11 @@ pub fn slice_index_range(slice: &[u32], index: Range<usize>) -> &[u32] {
 pub unsafe fn slice_get_unchecked_mut_range(slice: &mut [u32], index: Range<usize>) -> &mut [u32] {
     slice.get_unchecked_mut(index)
 }
+
+// EMIT_MIR slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.mir
+pub unsafe fn slice_ptr_get_unchecked_range(
+    slice: *const [u32],
+    index: Range<usize>,
+) -> *const [u32] {
+    slice.get_unchecked(index)
+}
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..79c6a05b48d
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,19 @@
+// MIR for `slice_ptr_get_unchecked_range` after PreCodegen
+
+fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -> *const [u32] {
+    debug slice => _1;
+    debug index => _2;
+    let mut _0: *const [u32];
+    scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
+        debug self => _1;
+        debug index => _2;
+    }
+
+    bb0: {
+        _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..5231f858d04
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,19 @@
+// MIR for `slice_ptr_get_unchecked_range` after PreCodegen
+
+fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -> *const [u32] {
+    debug slice => _1;
+    debug index => _2;
+    let mut _0: *const [u32];
+    scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
+        debug self => _1;
+        debug index => _2;
+    }
+
+    bb0: {
+        _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        return;
+    }
+}

From b76faff1b281fdf199e5abe8ff0c8d6d2e2e2a85 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Fri, 29 Mar 2024 00:37:31 -0700
Subject: [PATCH 05/15] Add a MIR pre-codegen test for Vec::deref

---
 tests/mir-opt/pre-codegen/vec_deref.rs             | 13 +++++++++++++
 ...deref_to_slice.PreCodegen.after.panic-abort.mir | 14 ++++++++++++++
 ...eref_to_slice.PreCodegen.after.panic-unwind.mir | 14 ++++++++++++++
 3 files changed, 41 insertions(+)
 create mode 100644 tests/mir-opt/pre-codegen/vec_deref.rs
 create mode 100644 tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
 create mode 100644 tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir

diff --git a/tests/mir-opt/pre-codegen/vec_deref.rs b/tests/mir-opt/pre-codegen/vec_deref.rs
new file mode 100644
index 00000000000..3476e1760c0
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/vec_deref.rs
@@ -0,0 +1,13 @@
+// skip-filecheck
+//@ compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=2
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+#![crate_type = "lib"]
+
+// Added after it stopped inlining in a nightly; see
+// <https://github.com/rust-lang/rust/issues/123174>
+
+// EMIT_MIR vec_deref.vec_deref_to_slice.PreCodegen.after.mir
+pub fn vec_deref_to_slice(v: &Vec<u8>) -> &[u8] {
+    v
+}
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
new file mode 100644
index 00000000000..df8d5c3836f
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,14 @@
+// MIR for `vec_deref_to_slice` after PreCodegen
+
+fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
+    debug v => _1;
+    let mut _0: &[u8];
+
+    bb0: {
+        _0 = <Vec<u8> as Deref>::deref(move _1) -> [return: bb1, unwind unreachable];
+    }
+
+    bb1: {
+        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
new file mode 100644
index 00000000000..d26afef4653
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/vec_deref.vec_deref_to_slice.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,14 @@
+// MIR for `vec_deref_to_slice` after PreCodegen
+
+fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
+    debug v => _1;
+    let mut _0: &[u8];
+
+    bb0: {
+        _0 = <Vec<u8> as Deref>::deref(move _1) -> [return: bb1, unwind continue];
+    }
+
+    bb1: {
+        return;
+    }
+}

From 70df9d9a1396f95eeef3fb765af09d47d14b3a8a Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Sun, 14 Apr 2024 11:26:45 -0700
Subject: [PATCH 06/15] Add a mir-opt test for `byte_add` on pointers

---
 ...e_add_fat.PreCodegen.after.panic-abort.mir | 62 +++++++++++++++++++
 ..._add_fat.PreCodegen.after.panic-unwind.mir | 62 +++++++++++++++++++
 ..._add_thin.PreCodegen.after.panic-abort.mir | 54 ++++++++++++++++
 ...add_thin.PreCodegen.after.panic-unwind.mir | 54 ++++++++++++++++
 tests/mir-opt/pre-codegen/ptr_offset.rs       | 16 +++++
 5 files changed, 248 insertions(+)
 create mode 100644 tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
 create mode 100644 tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
 create mode 100644 tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
 create mode 100644 tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
 create mode 100644 tests/mir-opt/pre-codegen/ptr_offset.rs

diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..81474306eec
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,62 @@
+// MIR for `demo_byte_add_fat` after PreCodegen
+
+fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
+    debug p => _1;
+    debug n => _2;
+    let mut _0: *const [u32];
+    scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::byte_add) {
+        debug self => _1;
+        debug count => _2;
+        let mut _3: *const u8;
+        let mut _4: *const u8;
+        scope 2 (inlined std::ptr::const_ptr::<impl *const [u32]>::cast::<u8>) {
+            debug self => _1;
+        }
+        scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
+            debug self => _3;
+            debug count => _2;
+        }
+        scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
+            debug self => _4;
+            debug meta => _1;
+            let mut _5: *const ();
+            let mut _7: usize;
+            scope 5 (inlined std::ptr::metadata::<[u32]>) {
+                debug ptr => _1;
+                let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
+            }
+            scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
+                debug data_pointer => _5;
+                debug metadata => _7;
+                let mut _8: std::ptr::metadata::PtrComponents<[u32]>;
+                let mut _9: std::ptr::metadata::PtrRepr<[u32]>;
+            }
+        }
+    }
+
+    bb0: {
+        StorageLive(_4);
+        StorageLive(_3);
+        _3 = _1 as *const u8 (PtrToPtr);
+        _4 = Offset(_3, _2);
+        StorageDead(_3);
+        StorageLive(_5);
+        _5 = _4 as *const () (PtrToPtr);
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
+        _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
+        StorageDead(_6);
+        StorageLive(_9);
+        StorageLive(_8);
+        _8 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: _5, metadata: _7 };
+        _9 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _8 };
+        StorageDead(_8);
+        _0 = (_9.0: *const [u32]);
+        StorageDead(_9);
+        StorageDead(_7);
+        StorageDead(_5);
+        StorageDead(_4);
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..81474306eec
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,62 @@
+// MIR for `demo_byte_add_fat` after PreCodegen
+
+fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
+    debug p => _1;
+    debug n => _2;
+    let mut _0: *const [u32];
+    scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::byte_add) {
+        debug self => _1;
+        debug count => _2;
+        let mut _3: *const u8;
+        let mut _4: *const u8;
+        scope 2 (inlined std::ptr::const_ptr::<impl *const [u32]>::cast::<u8>) {
+            debug self => _1;
+        }
+        scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
+            debug self => _3;
+            debug count => _2;
+        }
+        scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
+            debug self => _4;
+            debug meta => _1;
+            let mut _5: *const ();
+            let mut _7: usize;
+            scope 5 (inlined std::ptr::metadata::<[u32]>) {
+                debug ptr => _1;
+                let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
+            }
+            scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
+                debug data_pointer => _5;
+                debug metadata => _7;
+                let mut _8: std::ptr::metadata::PtrComponents<[u32]>;
+                let mut _9: std::ptr::metadata::PtrRepr<[u32]>;
+            }
+        }
+    }
+
+    bb0: {
+        StorageLive(_4);
+        StorageLive(_3);
+        _3 = _1 as *const u8 (PtrToPtr);
+        _4 = Offset(_3, _2);
+        StorageDead(_3);
+        StorageLive(_5);
+        _5 = _4 as *const () (PtrToPtr);
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
+        _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
+        StorageDead(_6);
+        StorageLive(_9);
+        StorageLive(_8);
+        _8 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: _5, metadata: _7 };
+        _9 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _8 };
+        StorageDead(_8);
+        _0 = (_9.0: *const [u32]);
+        StorageDead(_9);
+        StorageDead(_7);
+        StorageDead(_5);
+        StorageDead(_4);
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
new file mode 100644
index 00000000000..d86f2d1106a
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
@@ -0,0 +1,54 @@
+// MIR for `demo_byte_add_thin` after PreCodegen
+
+fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
+    debug p => _1;
+    debug n => _2;
+    let mut _0: *const u32;
+    scope 1 (inlined std::ptr::const_ptr::<impl *const u32>::byte_add) {
+        debug self => _1;
+        debug count => _2;
+        let mut _3: *const u8;
+        let mut _4: *const u8;
+        scope 2 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<u8>) {
+            debug self => _1;
+        }
+        scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
+            debug self => _3;
+            debug count => _2;
+        }
+        scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
+            debug self => _4;
+            debug meta => _1;
+            let mut _5: *const ();
+            scope 5 (inlined std::ptr::metadata::<u32>) {
+                debug ptr => _1;
+            }
+            scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
+                debug data_pointer => _5;
+                debug metadata => const ();
+                let mut _6: std::ptr::metadata::PtrComponents<u32>;
+                let mut _7: std::ptr::metadata::PtrRepr<u32>;
+            }
+        }
+    }
+
+    bb0: {
+        StorageLive(_4);
+        StorageLive(_3);
+        _3 = _1 as *const u8 (PtrToPtr);
+        _4 = Offset(_3, _2);
+        StorageDead(_3);
+        StorageLive(_5);
+        _5 = _4 as *const () (PtrToPtr);
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = std::ptr::metadata::PtrComponents::<u32> { data_pointer: _5, metadata: const () };
+        _7 = std::ptr::metadata::PtrRepr::<u32> { const_ptr: move _6 };
+        StorageDead(_6);
+        _0 = (_7.0: *const u32);
+        StorageDead(_7);
+        StorageDead(_5);
+        StorageDead(_4);
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
new file mode 100644
index 00000000000..d86f2d1106a
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
@@ -0,0 +1,54 @@
+// MIR for `demo_byte_add_thin` after PreCodegen
+
+fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
+    debug p => _1;
+    debug n => _2;
+    let mut _0: *const u32;
+    scope 1 (inlined std::ptr::const_ptr::<impl *const u32>::byte_add) {
+        debug self => _1;
+        debug count => _2;
+        let mut _3: *const u8;
+        let mut _4: *const u8;
+        scope 2 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<u8>) {
+            debug self => _1;
+        }
+        scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
+            debug self => _3;
+            debug count => _2;
+        }
+        scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
+            debug self => _4;
+            debug meta => _1;
+            let mut _5: *const ();
+            scope 5 (inlined std::ptr::metadata::<u32>) {
+                debug ptr => _1;
+            }
+            scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
+                debug data_pointer => _5;
+                debug metadata => const ();
+                let mut _6: std::ptr::metadata::PtrComponents<u32>;
+                let mut _7: std::ptr::metadata::PtrRepr<u32>;
+            }
+        }
+    }
+
+    bb0: {
+        StorageLive(_4);
+        StorageLive(_3);
+        _3 = _1 as *const u8 (PtrToPtr);
+        _4 = Offset(_3, _2);
+        StorageDead(_3);
+        StorageLive(_5);
+        _5 = _4 as *const () (PtrToPtr);
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = std::ptr::metadata::PtrComponents::<u32> { data_pointer: _5, metadata: const () };
+        _7 = std::ptr::metadata::PtrRepr::<u32> { const_ptr: move _6 };
+        StorageDead(_6);
+        _0 = (_7.0: *const u32);
+        StorageDead(_7);
+        StorageDead(_5);
+        StorageDead(_4);
+        return;
+    }
+}
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.rs b/tests/mir-opt/pre-codegen/ptr_offset.rs
new file mode 100644
index 00000000000..88ee00296a0
--- /dev/null
+++ b/tests/mir-opt/pre-codegen/ptr_offset.rs
@@ -0,0 +1,16 @@
+// skip-filecheck
+//@ compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2 -Zinline-mir
+//@ ignore-debug: precondition checks are under cfg(debug_assertions)
+// EMIT_MIR_FOR_EACH_PANIC_STRATEGY
+
+#![crate_type = "lib"]
+
+// EMIT_MIR ptr_offset.demo_byte_add_thin.PreCodegen.after.mir
+pub unsafe fn demo_byte_add_thin(p: *const u32, n: usize) -> *const u32 {
+    p.byte_add(n)
+}
+
+// EMIT_MIR ptr_offset.demo_byte_add_fat.PreCodegen.after.mir
+pub unsafe fn demo_byte_add_fat(p: *const [u32], n: usize) -> *const [u32] {
+    p.byte_add(n)
+}

From e6b2b764ecf08e3144274383e8f95e51fcaa6963 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Thu, 11 Apr 2024 14:44:02 -0700
Subject: [PATCH 07/15] Add `AggregateKind::RawPtr` and enough support to
 compile

---
 compiler/rustc_borrowck/src/lib.rs            |  3 +-
 compiler/rustc_borrowck/src/type_check/mod.rs |  9 ++++-
 .../src/transform/validate.rs                 | 38 +++++++++++++++++++
 compiler/rustc_middle/src/mir/pretty.rs       |  9 +++++
 compiler/rustc_middle/src/mir/syntax.rs       | 15 ++++++++
 compiler/rustc_middle/src/mir/tcx.rs          |  1 +
 compiler/rustc_middle/src/mir/visit.rs        |  3 ++
 compiler/rustc_mir_transform/src/gvn.rs       |  3 ++
 .../src/known_panics_lint.rs                  |  1 +
 .../rustc_smir/src/rustc_smir/convert/mir.rs  |  3 ++
 compiler/stable_mir/src/mir/body.rs           |  2 +
 11 files changed, 84 insertions(+), 3 deletions(-)

diff --git a/compiler/rustc_borrowck/src/lib.rs b/compiler/rustc_borrowck/src/lib.rs
index 7fbf4c47ec8..a69b644c4dc 100644
--- a/compiler/rustc_borrowck/src/lib.rs
+++ b/compiler/rustc_borrowck/src/lib.rs
@@ -1315,7 +1315,8 @@ impl<'cx, 'tcx> MirBorrowckCtxt<'cx, 'tcx> {
                     }
                     AggregateKind::Adt(..)
                     | AggregateKind::Array(..)
-                    | AggregateKind::Tuple { .. } => (),
+                    | AggregateKind::Tuple { .. }
+                    | AggregateKind::RawPtr(..) => (),
                 }
 
                 for operand in operands {
diff --git a/compiler/rustc_borrowck/src/type_check/mod.rs b/compiler/rustc_borrowck/src/type_check/mod.rs
index 0600a105459..61fa8466674 100644
--- a/compiler/rustc_borrowck/src/type_check/mod.rs
+++ b/compiler/rustc_borrowck/src/type_check/mod.rs
@@ -1921,7 +1921,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 }
             }
             AggregateKind::Array(ty) => Ok(ty),
-            AggregateKind::Tuple => {
+            AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
                 unreachable!("This should have been covered in check_rvalues");
             }
         }
@@ -2518,6 +2518,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 AggregateKind::Closure(_, _) => None,
                 AggregateKind::Coroutine(_, _) => None,
                 AggregateKind::CoroutineClosure(_, _) => None,
+                AggregateKind::RawPtr(_, _) => None,
             },
         }
     }
@@ -2539,6 +2540,10 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
             return;
         }
 
+        if let AggregateKind::RawPtr(..) = aggregate_kind {
+            bug!("RawPtr should only be in runtime MIR");
+        }
+
         for (i, operand) in operands.iter_enumerated() {
             let field_ty = match self.aggregate_field_ty(aggregate_kind, i, location) {
                 Ok(field_ty) => field_ty,
@@ -2757,7 +2762,7 @@ impl<'a, 'tcx> TypeChecker<'a, 'tcx> {
                 ),
             ),
 
-            AggregateKind::Array(_) | AggregateKind::Tuple => {
+            AggregateKind::Array(_) | AggregateKind::Tuple | AggregateKind::RawPtr(..) => {
                 (CRATE_DEF_ID.to_def_id(), ty::InstantiatedPredicates::empty())
             }
         };
diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index a499e4b980f..527325f1d6f 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -923,6 +923,44 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                         }
                     }
                 }
+                AggregateKind::RawPtr(pointee_ty, mutability) => {
+                    if !matches!(self.mir_phase, MirPhase::Runtime(_)) {
+                        // It would probably be fine to support this in earlier phases,
+                        // but at the time of writing it's only ever introduced from intrinsic lowering,
+                        // so earlier things just `bug!` on it.
+                        self.fail(location, "RawPtr should be in runtime MIR only");
+                    }
+
+                    if fields.len() != 2 {
+                        self.fail(location, "raw pointer aggregate must have 2 fields");
+                    } else {
+                        let data_ptr_ty = fields.raw[0].ty(self.body, self.tcx);
+                        let metadata_ty = fields.raw[1].ty(self.body, self.tcx);
+                        if let ty::RawPtr(in_pointee, in_mut) = data_ptr_ty.kind() {
+                            if *in_mut != mutability {
+                                self.fail(location, "input and output mutability must match");
+                            }
+
+                            // FIXME: check `Thin` instead of `Sized`
+                            if !in_pointee.is_sized(self.tcx, self.param_env) {
+                                self.fail(location, "input pointer must be thin");
+                            }
+                        } else {
+                            self.fail(location, "first operand to raw pointer aggregate must be a raw pointer");
+                        }
+
+                        // FIXME: Check metadata more generally
+                        if pointee_ty.is_slice() {
+                            if !self.mir_assign_valid_types(metadata_ty, self.tcx.types.usize) {
+                                self.fail(location, "slice metadata must be usize");
+                            }
+                        } else if pointee_ty.is_sized(self.tcx, self.param_env) {
+                            if metadata_ty != self.tcx.types.unit {
+                                self.fail(location, "metadata for pointer-to-thin must be unit");
+                            }
+                        }
+                    }
+                }
             },
             Rvalue::Ref(_, BorrowKind::Fake, _) => {
                 if self.mir_phase >= MirPhase::Runtime(RuntimePhase::Initial) {
diff --git a/compiler/rustc_middle/src/mir/pretty.rs b/compiler/rustc_middle/src/mir/pretty.rs
index a3cdcec9ec0..8291404ebf3 100644
--- a/compiler/rustc_middle/src/mir/pretty.rs
+++ b/compiler/rustc_middle/src/mir/pretty.rs
@@ -1094,6 +1094,15 @@ impl<'tcx> Debug for Rvalue<'tcx> {
 
                         struct_fmt.finish()
                     }),
+
+                    AggregateKind::RawPtr(pointee_ty, mutability) => {
+                        let kind_str = match mutability {
+                            Mutability::Mut => "mut",
+                            Mutability::Not => "const",
+                        };
+                        with_no_trimmed_paths!(write!(fmt, "*{kind_str} {pointee_ty} from "))?;
+                        fmt_tuple(fmt, "")
+                    }
                 }
             }
 
diff --git a/compiler/rustc_middle/src/mir/syntax.rs b/compiler/rustc_middle/src/mir/syntax.rs
index 97c3eb55638..db13bb9a3e8 100644
--- a/compiler/rustc_middle/src/mir/syntax.rs
+++ b/compiler/rustc_middle/src/mir/syntax.rs
@@ -1351,6 +1351,21 @@ pub enum AggregateKind<'tcx> {
     Closure(DefId, GenericArgsRef<'tcx>),
     Coroutine(DefId, GenericArgsRef<'tcx>),
     CoroutineClosure(DefId, GenericArgsRef<'tcx>),
+
+    /// Construct a raw pointer from the data pointer and metadata.
+    ///
+    /// The `Ty` here is the type of the *pointee*, not the pointer itself.
+    /// The `Mutability` indicates whether this produces a `*const` or `*mut`.
+    ///
+    /// The [`Rvalue::Aggregate`] operands for thus must be
+    ///
+    /// 0. A raw pointer of matching mutability with any [`core::ptr::Thin`] pointee
+    /// 1. A value of the appropriate [`core::ptr::Pointee::Metadata`] type
+    ///
+    /// *Both* operands must always be included, even the unit value if this is
+    /// creating a thin pointer. If you're just converting between thin pointers,
+    /// you may want an [`Rvalue::Cast`] with [`CastKind::PtrToPtr`] instead.
+    RawPtr(Ty<'tcx>, Mutability),
 }
 
 #[derive(Copy, Clone, Debug, PartialEq, Eq, TyEncodable, TyDecodable, Hash, HashStable)]
diff --git a/compiler/rustc_middle/src/mir/tcx.rs b/compiler/rustc_middle/src/mir/tcx.rs
index 506003ff7c0..abe99f3e95c 100644
--- a/compiler/rustc_middle/src/mir/tcx.rs
+++ b/compiler/rustc_middle/src/mir/tcx.rs
@@ -206,6 +206,7 @@ impl<'tcx> Rvalue<'tcx> {
                 AggregateKind::CoroutineClosure(did, args) => {
                     Ty::new_coroutine_closure(tcx, did, args)
                 }
+                AggregateKind::RawPtr(ty, mutability) => Ty::new_ptr(tcx, ty, mutability),
             },
             Rvalue::ShallowInitBox(_, ty) => Ty::new_box(tcx, ty),
             Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
diff --git a/compiler/rustc_middle/src/mir/visit.rs b/compiler/rustc_middle/src/mir/visit.rs
index 4f7b2f7cbe4..fc1ab0f12ac 100644
--- a/compiler/rustc_middle/src/mir/visit.rs
+++ b/compiler/rustc_middle/src/mir/visit.rs
@@ -751,6 +751,9 @@ macro_rules! make_mir_visitor {
                             ) => {
                                 self.visit_args(coroutine_closure_args, location);
                             }
+                            AggregateKind::RawPtr(ty, _) => {
+                                self.visit_ty($(& $mutability)? *ty, TyContext::Location(location));
+                            }
                         }
 
                         for operand in operands {
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs
index 8e8d78226c3..24832086b16 100644
--- a/compiler/rustc_mir_transform/src/gvn.rs
+++ b/compiler/rustc_mir_transform/src/gvn.rs
@@ -885,6 +885,7 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
                 AggregateKind::Adt(did, ..) => tcx.def_kind(did) != DefKind::Enum,
                 // Coroutines are never ZST, as they at least contain the implicit states.
                 AggregateKind::Coroutine(..) => false,
+                AggregateKind::RawPtr(..) => bug!("MIR for RawPtr aggregate must have 2 fields"),
             };
 
             if is_zst {
@@ -910,6 +911,8 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
             }
             // Do not track unions.
             AggregateKind::Adt(_, _, _, _, Some(_)) => return None,
+            // FIXME: Do the extra work to GVN `from_raw_parts`
+            AggregateKind::RawPtr(..) => return None,
         };
 
         let fields: Option<Vec<_>> = fields
diff --git a/compiler/rustc_mir_transform/src/known_panics_lint.rs b/compiler/rustc_mir_transform/src/known_panics_lint.rs
index 2744026a7c9..b8dbf8a759f 100644
--- a/compiler/rustc_mir_transform/src/known_panics_lint.rs
+++ b/compiler/rustc_mir_transform/src/known_panics_lint.rs
@@ -603,6 +603,7 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
                         AggregateKind::Adt(_, variant, _, _, _) => variant,
                         AggregateKind::Array(_)
                         | AggregateKind::Tuple
+                        | AggregateKind::RawPtr(_, _)
                         | AggregateKind::Closure(_, _)
                         | AggregateKind::Coroutine(_, _)
                         | AggregateKind::CoroutineClosure(_, _) => VariantIdx::ZERO,
diff --git a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
index c9f66612590..7c021621103 100644
--- a/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
+++ b/compiler/rustc_smir/src/rustc_smir/convert/mir.rs
@@ -543,6 +543,9 @@ impl<'tcx> Stable<'tcx> for mir::AggregateKind<'tcx> {
             mir::AggregateKind::CoroutineClosure(..) => {
                 todo!("FIXME(async_closures): Lower these to SMIR")
             }
+            mir::AggregateKind::RawPtr(ty, mutability) => {
+                stable_mir::mir::AggregateKind::RawPtr(ty.stable(tables), mutability.stable(tables))
+            }
         }
     }
 }
diff --git a/compiler/stable_mir/src/mir/body.rs b/compiler/stable_mir/src/mir/body.rs
index 1ad05633d62..6f666406c22 100644
--- a/compiler/stable_mir/src/mir/body.rs
+++ b/compiler/stable_mir/src/mir/body.rs
@@ -602,6 +602,7 @@ impl Rvalue {
                 AggregateKind::Coroutine(def, ref args, mov) => {
                     Ok(Ty::new_coroutine(def, args.clone(), mov))
                 }
+                AggregateKind::RawPtr(ty, mutability) => Ok(Ty::new_ptr(ty, mutability)),
             },
             Rvalue::ShallowInitBox(_, ty) => Ok(Ty::new_box(*ty)),
             Rvalue::CopyForDeref(place) => place.ty(locals),
@@ -617,6 +618,7 @@ pub enum AggregateKind {
     Closure(ClosureDef, GenericArgs),
     // FIXME(stable_mir): Movability here is redundant
     Coroutine(CoroutineDef, GenericArgs, Movability),
+    RawPtr(Ty, Mutability),
 }
 
 #[derive(Clone, Debug, Eq, PartialEq)]

From 4f4442655ee755b68fc04386f243c637a64f8320 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Thu, 11 Apr 2024 15:33:37 -0700
Subject: [PATCH 08/15] Add an intrinsic that lowers to AggregateKind::RawPtr

---
 .../src/transform/validate.rs                 |  5 +-
 .../rustc_hir_analysis/src/check/intrinsic.rs |  5 +
 .../src/lower_intrinsics.rs                   | 28 ++++++
 compiler/rustc_span/src/symbol.rs             |  1 +
 library/core/src/intrinsics.rs                | 26 +++++
 ..._pointers.LowerIntrinsics.panic-abort.diff | 95 +++++++++++++++++++
 ...pointers.LowerIntrinsics.panic-unwind.diff | 95 +++++++++++++++++++
 tests/mir-opt/lower_intrinsics.rs             | 10 ++
 8 files changed, 264 insertions(+), 1 deletion(-)
 create mode 100644 tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-abort.diff
 create mode 100644 tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-unwind.diff

diff --git a/compiler/rustc_const_eval/src/transform/validate.rs b/compiler/rustc_const_eval/src/transform/validate.rs
index 527325f1d6f..bf5592c828f 100644
--- a/compiler/rustc_const_eval/src/transform/validate.rs
+++ b/compiler/rustc_const_eval/src/transform/validate.rs
@@ -946,7 +946,10 @@ impl<'a, 'tcx> Visitor<'tcx> for TypeChecker<'a, 'tcx> {
                                 self.fail(location, "input pointer must be thin");
                             }
                         } else {
-                            self.fail(location, "first operand to raw pointer aggregate must be a raw pointer");
+                            self.fail(
+                                location,
+                                "first operand to raw pointer aggregate must be a raw pointer",
+                            );
                         }
 
                         // FIXME: Check metadata more generally
diff --git a/compiler/rustc_hir_analysis/src/check/intrinsic.rs b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
index bd64621f077..fb4a76bf089 100644
--- a/compiler/rustc_hir_analysis/src/check/intrinsic.rs
+++ b/compiler/rustc_hir_analysis/src/check/intrinsic.rs
@@ -128,6 +128,7 @@ pub fn intrinsic_operation_unsafety(tcx: TyCtxt<'_>, intrinsic_id: LocalDefId) -
         | sym::variant_count
         | sym::is_val_statically_known
         | sym::ptr_mask
+        | sym::aggregate_raw_ptr
         | sym::ub_checks
         | sym::fadd_algebraic
         | sym::fsub_algebraic
@@ -574,6 +575,10 @@ pub fn check_intrinsic_type(
                 (0, 0, vec![Ty::new_imm_ptr(tcx, Ty::new_unit(tcx))], tcx.types.usize)
             }
 
+            // This type check is not particularly useful, but the `where` bounds
+            // on the definition in `core` do the heavy lifting for checking it.
+            sym::aggregate_raw_ptr => (3, 1, vec![param(1), param(2)], param(0)),
+
             sym::ub_checks => (0, 1, Vec::new(), tcx.types.bool),
 
             sym::simd_eq
diff --git a/compiler/rustc_mir_transform/src/lower_intrinsics.rs b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
index 7e8920604c1..da63fcf23d9 100644
--- a/compiler/rustc_mir_transform/src/lower_intrinsics.rs
+++ b/compiler/rustc_mir_transform/src/lower_intrinsics.rs
@@ -287,6 +287,34 @@ impl<'tcx> MirPass<'tcx> for LowerIntrinsics {
                             terminator.kind = TerminatorKind::Unreachable;
                         }
                     }
+                    sym::aggregate_raw_ptr => {
+                        let Ok([data, meta]) = <[_; 2]>::try_from(std::mem::take(args)) else {
+                            span_bug!(
+                                terminator.source_info.span,
+                                "Wrong number of arguments for aggregate_raw_ptr intrinsic",
+                            );
+                        };
+                        let target = target.unwrap();
+                        let pointer_ty = generic_args.type_at(0);
+                        let kind = if let ty::RawPtr(pointee_ty, mutability) = pointer_ty.kind() {
+                            AggregateKind::RawPtr(*pointee_ty, *mutability)
+                        } else {
+                            span_bug!(
+                                terminator.source_info.span,
+                                "Return type of aggregate_raw_ptr intrinsic must be a raw pointer",
+                            );
+                        };
+                        let fields = [data.node, meta.node];
+                        block.statements.push(Statement {
+                            source_info: terminator.source_info,
+                            kind: StatementKind::Assign(Box::new((
+                                *destination,
+                                Rvalue::Aggregate(Box::new(kind), fields.into()),
+                            ))),
+                        });
+
+                        terminator.kind = TerminatorKind::Goto { target };
+                    }
                     _ => {}
                 }
             }
diff --git a/compiler/rustc_span/src/symbol.rs b/compiler/rustc_span/src/symbol.rs
index 46bae1c1e98..f5eeb3d4ff1 100644
--- a/compiler/rustc_span/src/symbol.rs
+++ b/compiler/rustc_span/src/symbol.rs
@@ -361,6 +361,7 @@ symbols! {
         adt_const_params,
         advanced_slice_patterns,
         adx_target_feature,
+        aggregate_raw_ptr,
         alias,
         align,
         align_offset,
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 9406efd7ab2..b49409a9f42 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2779,6 +2779,32 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
     unreachable!()
 }
 
+/// Lowers in MIR to `Rvalue::Aggregate` with `AggregateKind::RawPtr`.
+///
+/// This is used to implement functions like `slice::from_raw_parts_mut` and
+/// `ptr::from_raw_parts` in a way compatible with the compiler being able to
+/// change the possible layouts of pointers.
+#[rustc_nounwind]
+#[unstable(feature = "core_intrinsics", issue = "none")]
+#[rustc_intrinsic]
+#[rustc_intrinsic_must_be_overridden]
+#[cfg(not(bootstrap))]
+pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(_data: D, _meta: M) -> P {
+    // No fallback because `libcore` doesn't want to know the layout
+    unreachable!()
+}
+
+#[unstable(feature = "core_intrinsics", issue = "none")]
+pub trait AggregateRawPtr<D> {
+    type Metadata: Copy;
+}
+impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*const T> for *const P {
+    type Metadata = <P as ptr::Pointee>::Metadata;
+}
+impl<P: ?Sized, T: ptr::Thin> AggregateRawPtr<*mut T> for *mut P {
+    type Metadata = <P as ptr::Pointee>::Metadata;
+}
+
 // Some functions are defined here because they accidentally got made
 // available in this module on stable. See <https://github.com/rust-lang/rust/issues/15702>.
 // (`transmute` also falls into this category, but it cannot be wrapped due to the
diff --git a/tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-abort.diff
new file mode 100644
index 00000000000..02934d4c01e
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-abort.diff
@@ -0,0 +1,95 @@
+- // MIR for `make_pointers` before LowerIntrinsics
++ // MIR for `make_pointers` after LowerIntrinsics
+  
+  fn make_pointers(_1: *const u8, _2: *mut (), _3: usize) -> () {
+      debug a => _1;
+      debug b => _2;
+      debug n => _3;
+      let mut _0: ();
+      let _4: *const i32;
+      let mut _5: *const u8;
+      let mut _6: ();
+      let mut _8: *mut ();
+      let mut _9: ();
+      let mut _11: *const u8;
+      let mut _12: usize;
+      let mut _14: *mut ();
+      let mut _15: usize;
+      scope 1 {
+          debug _thin_const => _4;
+          let _7: *mut u8;
+          scope 2 {
+              debug _thin_mut => _7;
+              let _10: *const [u16];
+              scope 3 {
+                  debug _slice_const => _10;
+                  let _13: *mut [u64];
+                  scope 4 {
+                      debug _slice_mut => _13;
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = _1;
+          StorageLive(_6);
+          _6 = ();
+-         _4 = aggregate_raw_ptr::<*const i32, *const u8, ()>(move _5, move _6) -> [return: bb1, unwind unreachable];
++         _4 = *const i32 from (move _5, move _6);
++         goto -> bb1;
+      }
+  
+      bb1: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_7);
+          StorageLive(_8);
+          _8 = _2;
+          StorageLive(_9);
+          _9 = ();
+-         _7 = aggregate_raw_ptr::<*mut u8, *mut (), ()>(move _8, move _9) -> [return: bb2, unwind unreachable];
++         _7 = *mut u8 from (move _8, move _9);
++         goto -> bb2;
+      }
+  
+      bb2: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = _1;
+          StorageLive(_12);
+          _12 = _3;
+-         _10 = aggregate_raw_ptr::<*const [u16], *const u8, usize>(move _11, move _12) -> [return: bb3, unwind unreachable];
++         _10 = *const [u16] from (move _11, move _12);
++         goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          StorageLive(_14);
+          _14 = _2;
+          StorageLive(_15);
+          _15 = _3;
+-         _13 = aggregate_raw_ptr::<*mut [u64], *mut (), usize>(move _14, move _15) -> [return: bb4, unwind unreachable];
++         _13 = *mut [u64] from (move _14, move _15);
++         goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_15);
+          StorageDead(_14);
+          _0 = const ();
+          StorageDead(_13);
+          StorageDead(_10);
+          StorageDead(_7);
+          StorageDead(_4);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-unwind.diff
new file mode 100644
index 00000000000..02934d4c01e
--- /dev/null
+++ b/tests/mir-opt/lower_intrinsics.make_pointers.LowerIntrinsics.panic-unwind.diff
@@ -0,0 +1,95 @@
+- // MIR for `make_pointers` before LowerIntrinsics
++ // MIR for `make_pointers` after LowerIntrinsics
+  
+  fn make_pointers(_1: *const u8, _2: *mut (), _3: usize) -> () {
+      debug a => _1;
+      debug b => _2;
+      debug n => _3;
+      let mut _0: ();
+      let _4: *const i32;
+      let mut _5: *const u8;
+      let mut _6: ();
+      let mut _8: *mut ();
+      let mut _9: ();
+      let mut _11: *const u8;
+      let mut _12: usize;
+      let mut _14: *mut ();
+      let mut _15: usize;
+      scope 1 {
+          debug _thin_const => _4;
+          let _7: *mut u8;
+          scope 2 {
+              debug _thin_mut => _7;
+              let _10: *const [u16];
+              scope 3 {
+                  debug _slice_const => _10;
+                  let _13: *mut [u64];
+                  scope 4 {
+                      debug _slice_mut => _13;
+                  }
+              }
+          }
+      }
+  
+      bb0: {
+          StorageLive(_4);
+          StorageLive(_5);
+          _5 = _1;
+          StorageLive(_6);
+          _6 = ();
+-         _4 = aggregate_raw_ptr::<*const i32, *const u8, ()>(move _5, move _6) -> [return: bb1, unwind unreachable];
++         _4 = *const i32 from (move _5, move _6);
++         goto -> bb1;
+      }
+  
+      bb1: {
+          StorageDead(_6);
+          StorageDead(_5);
+          StorageLive(_7);
+          StorageLive(_8);
+          _8 = _2;
+          StorageLive(_9);
+          _9 = ();
+-         _7 = aggregate_raw_ptr::<*mut u8, *mut (), ()>(move _8, move _9) -> [return: bb2, unwind unreachable];
++         _7 = *mut u8 from (move _8, move _9);
++         goto -> bb2;
+      }
+  
+      bb2: {
+          StorageDead(_9);
+          StorageDead(_8);
+          StorageLive(_10);
+          StorageLive(_11);
+          _11 = _1;
+          StorageLive(_12);
+          _12 = _3;
+-         _10 = aggregate_raw_ptr::<*const [u16], *const u8, usize>(move _11, move _12) -> [return: bb3, unwind unreachable];
++         _10 = *const [u16] from (move _11, move _12);
++         goto -> bb3;
+      }
+  
+      bb3: {
+          StorageDead(_12);
+          StorageDead(_11);
+          StorageLive(_13);
+          StorageLive(_14);
+          _14 = _2;
+          StorageLive(_15);
+          _15 = _3;
+-         _13 = aggregate_raw_ptr::<*mut [u64], *mut (), usize>(move _14, move _15) -> [return: bb4, unwind unreachable];
++         _13 = *mut [u64] from (move _14, move _15);
++         goto -> bb4;
+      }
+  
+      bb4: {
+          StorageDead(_15);
+          StorageDead(_14);
+          _0 = const ();
+          StorageDead(_13);
+          StorageDead(_10);
+          StorageDead(_7);
+          StorageDead(_4);
+          return;
+      }
+  }
+  
diff --git a/tests/mir-opt/lower_intrinsics.rs b/tests/mir-opt/lower_intrinsics.rs
index 693425c0041..12e526ab074 100644
--- a/tests/mir-opt/lower_intrinsics.rs
+++ b/tests/mir-opt/lower_intrinsics.rs
@@ -248,3 +248,13 @@ pub fn three_way_compare_signed(a: i16, b: i16) {
 pub fn three_way_compare_unsigned(a: u32, b: u32) {
     let _x = core::intrinsics::three_way_compare(a, b);
 }
+
+// EMIT_MIR lower_intrinsics.make_pointers.LowerIntrinsics.diff
+pub fn make_pointers(a: *const u8, b: *mut (), n: usize) {
+    use std::intrinsics::aggregate_raw_ptr;
+
+    let _thin_const: *const i32 = aggregate_raw_ptr(a, ());
+    let _thin_mut: *mut u8 = aggregate_raw_ptr(b, ());
+    let _slice_const: *const [u16] = aggregate_raw_ptr(a, n);
+    let _slice_mut: *mut [u64] = aggregate_raw_ptr(b, n);
+}

From de64ff76f8abd65222f9f6db56e7652976c5339b Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Thu, 11 Apr 2024 17:01:27 -0700
Subject: [PATCH 09/15] Use it in the library, and `InstSimplify` it away in
 the easy places

---
 compiler/rustc_codegen_ssa/src/mir/rvalue.rs  | 22 ++++++-
 .../rustc_const_eval/src/interpret/operand.rs | 11 ++++
 .../rustc_const_eval/src/interpret/step.rs    | 17 ++++-
 library/core/src/intrinsics.rs                |  1 +
 library/core/src/ptr/metadata.rs              | 32 ++++++---
 library/core/tests/ptr.rs                     |  8 +++
 library/core/tests/slice.rs                   | 13 ++++
 ...ked_range.PreCodegen.after.panic-abort.mir | 60 +++++++++++++++--
 ...ed_range.PreCodegen.after.panic-unwind.mir | 60 +++++++++++++++--
 ..._to_slice.PreCodegen.after.panic-abort.mir | 66 +++++++++++++++++--
 ...to_slice.PreCodegen.after.panic-unwind.mir | 66 +++++++++++++++++--
 11 files changed, 328 insertions(+), 28 deletions(-)

diff --git a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
index 6725a6d9e38..7823d4c249a 100644
--- a/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
+++ b/compiler/rustc_codegen_ssa/src/mir/rvalue.rs
@@ -9,7 +9,7 @@ use crate::MemFlags;
 
 use rustc_hir as hir;
 use rustc_middle::mir;
-use rustc_middle::mir::Operand;
+use rustc_middle::mir::{AggregateKind, Operand};
 use rustc_middle::ty::cast::{CastTy, IntTy};
 use rustc_middle::ty::layout::{HasTyCtxt, LayoutOf, TyAndLayout};
 use rustc_middle::ty::{self, adjustment::PointerCoercion, Instance, Ty, TyCtxt};
@@ -720,6 +720,24 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
                 OperandRef { val: OperandValue::Immediate(static_), layout }
             }
             mir::Rvalue::Use(ref operand) => self.codegen_operand(bx, operand),
+            mir::Rvalue::Aggregate(box mir::AggregateKind::RawPtr(..), ref fields) => {
+                let ty = rvalue.ty(self.mir, self.cx.tcx());
+                let layout = self.cx.layout_of(self.monomorphize(ty));
+                let [data, meta] = &*fields.raw else {
+                    bug!("RawPtr fields: {fields:?}");
+                };
+                let data = self.codegen_operand(bx, data);
+                let meta = self.codegen_operand(bx, meta);
+                match (data.val, meta.val) {
+                    (p @ OperandValue::Immediate(_), OperandValue::ZeroSized) => {
+                        OperandRef { val: p, layout }
+                    }
+                    (OperandValue::Immediate(p), OperandValue::Immediate(m)) => {
+                        OperandRef { val: OperandValue::Pair(p, m), layout }
+                    }
+                    _ => bug!("RawPtr operands {data:?} {meta:?}"),
+                }
+            }
             mir::Rvalue::Repeat(..) | mir::Rvalue::Aggregate(..) => {
                 // According to `rvalue_creates_operand`, only ZST
                 // aggregate rvalues are allowed to be operands.
@@ -1032,6 +1050,8 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
             mir::Rvalue::ThreadLocalRef(_) |
             mir::Rvalue::Use(..) => // (*)
                 true,
+            // This always produces a `ty::RawPtr`, so will be Immediate or Pair
+            mir::Rvalue::Aggregate(box AggregateKind::RawPtr(..), ..) => true,
             mir::Rvalue::Repeat(..) |
             mir::Rvalue::Aggregate(..) => {
                 let ty = rvalue.ty(self.mir, self.cx.tcx());
diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index 718c91b2f76..d4a6dab9ac3 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -603,6 +603,17 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         Ok(self.read_immediate(op)?.to_scalar())
     }
 
+    pub fn read_mem_place_meta(
+        &self,
+        op: &impl Readable<'tcx, M::Provenance>,
+    ) -> InterpResult<'tcx, MemPlaceMeta<M::Provenance>> {
+        Ok(if op.layout().is_zst() {
+            MemPlaceMeta::None
+        } else {
+            MemPlaceMeta::Meta(self.read_scalar(op)?)
+        })
+    }
+
     // Pointer-sized reads are fairly common and need target layout access, so we wrap them in
     // convenience functions.
 
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index c3f26da8a79..460cd377c8f 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,7 +9,7 @@ use rustc_middle::mir;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
 
-use super::{ImmTy, InterpCx, InterpResult, Machine, PlaceTy, Projectable, Scalar};
+use super::{ImmTy, Immediate, InterpCx, InterpResult, Machine, PlaceTy, Projectable, Scalar};
 use crate::util;
 
 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
@@ -303,6 +303,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 let variant_dest = self.project_downcast(dest, variant_index)?;
                 (variant_index, variant_dest, active_field_index)
             }
+            mir::AggregateKind::RawPtr(..) => {
+                // Trying to `project_field` into pointers tends not to work,
+                // so build the `Immediate` from the parts directly.
+                let [data, meta] = &operands.raw else {
+                    bug!("{kind:?} should have 2 operands, had {operands:?}");
+                };
+                let data = self.eval_operand(data, None)?;
+                let data = self.read_pointer(&data)?;
+                let meta = self.eval_operand(meta, None)?;
+                let meta = self.read_mem_place_meta(&meta)?;
+                let ptr_imm = Immediate::new_pointer_with_meta(data, meta, self);
+                let ptr = ImmTy::from_immediate(ptr_imm, dest.layout);
+                self.copy_op(&ptr, dest)?;
+                return Ok(());
+            }
             _ => (FIRST_VARIANT, dest.clone(), None),
         };
         if active_field_index.is_some() {
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index b49409a9f42..751f2210d0c 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2786,6 +2786,7 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
 /// change the possible layouts of pointers.
 #[rustc_nounwind]
 #[unstable(feature = "core_intrinsics", issue = "none")]
+#[rustc_const_unstable(feature = "ptr_metadata", issue = "81513")]
 #[rustc_intrinsic]
 #[rustc_intrinsic_must_be_overridden]
 #[cfg(not(bootstrap))]
diff --git a/library/core/src/ptr/metadata.rs b/library/core/src/ptr/metadata.rs
index 25a06f121cd..1226c8e2419 100644
--- a/library/core/src/ptr/metadata.rs
+++ b/library/core/src/ptr/metadata.rs
@@ -2,6 +2,8 @@
 
 use crate::fmt;
 use crate::hash::{Hash, Hasher};
+#[cfg(not(bootstrap))]
+use crate::intrinsics::aggregate_raw_ptr;
 use crate::marker::Freeze;
 
 /// Provides the pointer metadata type of any pointed-to type.
@@ -113,10 +115,17 @@ pub const fn from_raw_parts<T: ?Sized>(
     data_pointer: *const (),
     metadata: <T as Pointee>::Metadata,
 ) -> *const T {
-    // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
-    // and PtrComponents<T> have the same memory layouts. Only std can make this
-    // guarantee.
-    unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr }
+    #[cfg(bootstrap)]
+    {
+        // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
+        // and PtrComponents<T> have the same memory layouts. Only std can make this
+        // guarantee.
+        unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.const_ptr }
+    }
+    #[cfg(not(bootstrap))]
+    {
+        aggregate_raw_ptr(data_pointer, metadata)
+    }
 }
 
 /// Performs the same functionality as [`from_raw_parts`], except that a
@@ -130,10 +139,17 @@ pub const fn from_raw_parts_mut<T: ?Sized>(
     data_pointer: *mut (),
     metadata: <T as Pointee>::Metadata,
 ) -> *mut T {
-    // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
-    // and PtrComponents<T> have the same memory layouts. Only std can make this
-    // guarantee.
-    unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
+    #[cfg(bootstrap)]
+    {
+        // SAFETY: Accessing the value from the `PtrRepr` union is safe since *const T
+        // and PtrComponents<T> have the same memory layouts. Only std can make this
+        // guarantee.
+        unsafe { PtrRepr { components: PtrComponents { data_pointer, metadata } }.mut_ptr }
+    }
+    #[cfg(not(bootstrap))]
+    {
+        aggregate_raw_ptr(data_pointer, metadata)
+    }
 }
 
 #[repr(C)]
diff --git a/library/core/tests/ptr.rs b/library/core/tests/ptr.rs
index 2c82eda9a58..7b55c2bf8a8 100644
--- a/library/core/tests/ptr.rs
+++ b/library/core/tests/ptr.rs
@@ -1163,3 +1163,11 @@ fn test_null_array_as_slice() {
     assert!(ptr.is_null());
     assert_eq!(ptr.len(), 4);
 }
+
+#[test]
+fn test_ptr_from_raw_parts_in_const() {
+    const EMPTY_SLICE_PTR: *const [i32] =
+        std::ptr::slice_from_raw_parts(std::ptr::without_provenance(123), 456);
+    assert_eq!(EMPTY_SLICE_PTR.addr(), 123);
+    assert_eq!(EMPTY_SLICE_PTR.len(), 456);
+}
diff --git a/library/core/tests/slice.rs b/library/core/tests/slice.rs
index c5743eda3e8..ffe8ffcc7f2 100644
--- a/library/core/tests/slice.rs
+++ b/library/core/tests/slice.rs
@@ -2678,3 +2678,16 @@ fn test_get_many_mut_duplicate() {
     let mut v = vec![1, 2, 3, 4, 5];
     assert!(v.get_many_mut([1, 3, 3, 4]).is_err());
 }
+
+#[test]
+fn test_slice_from_raw_parts_in_const() {
+    static FANCY: i32 = 4;
+    static FANCY_SLICE: &[i32] = unsafe { std::slice::from_raw_parts(&FANCY, 1) };
+    assert_eq!(FANCY_SLICE.as_ptr(), std::ptr::addr_of!(FANCY));
+    assert_eq!(FANCY_SLICE.len(), 1);
+
+    const EMPTY_SLICE: &[i32] =
+        unsafe { std::slice::from_raw_parts(std::ptr::without_provenance(123456), 0) };
+    assert_eq!(EMPTY_SLICE.as_ptr().addr(), 123456);
+    assert_eq!(EMPTY_SLICE.len(), 0);
+}
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
index 79c6a05b48d..8446324c663 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
@@ -4,16 +4,66 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
     debug slice => _1;
     debug index => _2;
     let mut _0: *const [u32];
+    let mut _3: usize;
+    let mut _4: usize;
     scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
         debug self => _1;
-        debug index => _2;
+        debug ((index: std::ops::Range<usize>).0: usize) => _3;
+        debug ((index: std::ops::Range<usize>).1: usize) => _4;
+        scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) {
+            debug ((self: std::ops::Range<usize>).0: usize) => _3;
+            debug ((self: std::ops::Range<usize>).1: usize) => _4;
+            debug slice => _1;
+            let _5: usize;
+            let mut _6: *const u32;
+            let mut _7: *const u32;
+            scope 3 {
+                debug new_len => _5;
+                scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) {
+                    debug self => _1;
+                }
+                scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) {
+                    debug self => _6;
+                    debug count => _3;
+                }
+                scope 8 (inlined slice_from_raw_parts::<u32>) {
+                    debug data => _7;
+                    debug len => _5;
+                    let mut _8: *const ();
+                    scope 9 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<()>) {
+                        debug self => _7;
+                    }
+                    scope 10 (inlined std::ptr::from_raw_parts::<[u32]>) {
+                        debug data_pointer => _8;
+                        debug metadata => _5;
+                    }
+                }
+            }
+            scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) {
+                debug self => _1;
+                scope 5 (inlined std::ptr::metadata::<[u32]>) {
+                    debug ptr => _1;
+                }
+            }
+        }
     }
 
     bb0: {
-        _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind unreachable];
-    }
-
-    bb1: {
+        _3 = move (_2.0: usize);
+        _4 = move (_2.1: usize);
+        StorageLive(_5);
+        _5 = SubUnchecked(_4, _3);
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _1 as *const u32 (PtrToPtr);
+        _7 = Offset(_6, _3);
+        StorageDead(_6);
+        StorageLive(_8);
+        _8 = _7 as *const () (PtrToPtr);
+        _0 = *const [u32] from (_8, _5);
+        StorageDead(_8);
+        StorageDead(_7);
+        StorageDead(_5);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
index 5231f858d04..8446324c663 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
@@ -4,16 +4,66 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
     debug slice => _1;
     debug index => _2;
     let mut _0: *const [u32];
+    let mut _3: usize;
+    let mut _4: usize;
     scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
         debug self => _1;
-        debug index => _2;
+        debug ((index: std::ops::Range<usize>).0: usize) => _3;
+        debug ((index: std::ops::Range<usize>).1: usize) => _4;
+        scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) {
+            debug ((self: std::ops::Range<usize>).0: usize) => _3;
+            debug ((self: std::ops::Range<usize>).1: usize) => _4;
+            debug slice => _1;
+            let _5: usize;
+            let mut _6: *const u32;
+            let mut _7: *const u32;
+            scope 3 {
+                debug new_len => _5;
+                scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) {
+                    debug self => _1;
+                }
+                scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) {
+                    debug self => _6;
+                    debug count => _3;
+                }
+                scope 8 (inlined slice_from_raw_parts::<u32>) {
+                    debug data => _7;
+                    debug len => _5;
+                    let mut _8: *const ();
+                    scope 9 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<()>) {
+                        debug self => _7;
+                    }
+                    scope 10 (inlined std::ptr::from_raw_parts::<[u32]>) {
+                        debug data_pointer => _8;
+                        debug metadata => _5;
+                    }
+                }
+            }
+            scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) {
+                debug self => _1;
+                scope 5 (inlined std::ptr::metadata::<[u32]>) {
+                    debug ptr => _1;
+                }
+            }
+        }
     }
 
     bb0: {
-        _0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked(move _2, move _1) -> [return: bb1, unwind continue];
-    }
-
-    bb1: {
+        _3 = move (_2.0: usize);
+        _4 = move (_2.1: usize);
+        StorageLive(_5);
+        _5 = SubUnchecked(_4, _3);
+        StorageLive(_7);
+        StorageLive(_6);
+        _6 = _1 as *const u32 (PtrToPtr);
+        _7 = Offset(_6, _3);
+        StorageDead(_6);
+        StorageLive(_8);
+        _8 = _7 as *const () (PtrToPtr);
+        _0 = *const [u32] from (_8, _5);
+        StorageDead(_8);
+        StorageDead(_7);
+        StorageDead(_5);
         return;
     }
 }
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 df8d5c3836f..18728d543ad 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
@@ -3,12 +3,70 @@
 fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     debug v => _1;
     let mut _0: &[u8];
-
-    bb0: {
-        _0 = <Vec<u8> as Deref>::deref(move _1) -> [return: bb1, unwind unreachable];
+    scope 1 (inlined <Vec<u8> as Deref>::deref) {
+        debug self => _1;
+        let mut _4: *const u8;
+        let mut _5: usize;
+        scope 2 (inlined Vec::<u8>::as_ptr) {
+            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: std::ptr::NonNull<u8>;
+                scope 4 (inlined Unique::<u8>::as_ptr) {
+                    debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
+                    debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
+                    scope 5 (inlined NonNull::<u8>::as_ptr) {
+                        debug self => _3;
+                    }
+                }
+            }
+        }
+        scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
+            debug data => _4;
+            debug len => _5;
+            let _7: *const [u8];
+            scope 7 (inlined core::ub_checks::check_language_ub) {
+                scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
+                }
+            }
+            scope 9 (inlined std::mem::size_of::<u8>) {
+            }
+            scope 10 (inlined align_of::<u8>) {
+            }
+            scope 11 (inlined slice_from_raw_parts::<u8>) {
+                debug data => _4;
+                debug len => _5;
+                let mut _6: *const ();
+                scope 12 (inlined std::ptr::const_ptr::<impl *const u8>::cast::<()>) {
+                    debug self => _4;
+                }
+                scope 13 (inlined std::ptr::from_raw_parts::<[u8]>) {
+                    debug data_pointer => _6;
+                    debug metadata => _5;
+                }
+            }
+        }
     }
 
-    bb1: {
+    bb0: {
+        StorageLive(_4);
+        StorageLive(_2);
+        _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
+        StorageLive(_3);
+        _3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
+        _4 = (_3.0: *const u8);
+        StorageDead(_3);
+        StorageDead(_2);
+        StorageLive(_5);
+        _5 = ((*_1).1: usize);
+        StorageLive(_6);
+        _6 = _4 as *const () (PtrToPtr);
+        _7 = *const [u8] from (_6, _5);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageDead(_4);
+        _0 = &(*_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 d26afef4653..18728d543ad 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
@@ -3,12 +3,70 @@
 fn vec_deref_to_slice(_1: &Vec<u8>) -> &[u8] {
     debug v => _1;
     let mut _0: &[u8];
-
-    bb0: {
-        _0 = <Vec<u8> as Deref>::deref(move _1) -> [return: bb1, unwind continue];
+    scope 1 (inlined <Vec<u8> as Deref>::deref) {
+        debug self => _1;
+        let mut _4: *const u8;
+        let mut _5: usize;
+        scope 2 (inlined Vec::<u8>::as_ptr) {
+            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: std::ptr::NonNull<u8>;
+                scope 4 (inlined Unique::<u8>::as_ptr) {
+                    debug ((self: Unique<u8>).0: std::ptr::NonNull<u8>) => _3;
+                    debug ((self: Unique<u8>).1: std::marker::PhantomData<u8>) => const PhantomData::<u8>;
+                    scope 5 (inlined NonNull::<u8>::as_ptr) {
+                        debug self => _3;
+                    }
+                }
+            }
+        }
+        scope 6 (inlined std::slice::from_raw_parts::<'_, u8>) {
+            debug data => _4;
+            debug len => _5;
+            let _7: *const [u8];
+            scope 7 (inlined core::ub_checks::check_language_ub) {
+                scope 8 (inlined core::ub_checks::check_language_ub::runtime) {
+                }
+            }
+            scope 9 (inlined std::mem::size_of::<u8>) {
+            }
+            scope 10 (inlined align_of::<u8>) {
+            }
+            scope 11 (inlined slice_from_raw_parts::<u8>) {
+                debug data => _4;
+                debug len => _5;
+                let mut _6: *const ();
+                scope 12 (inlined std::ptr::const_ptr::<impl *const u8>::cast::<()>) {
+                    debug self => _4;
+                }
+                scope 13 (inlined std::ptr::from_raw_parts::<[u8]>) {
+                    debug data_pointer => _6;
+                    debug metadata => _5;
+                }
+            }
+        }
     }
 
-    bb1: {
+    bb0: {
+        StorageLive(_4);
+        StorageLive(_2);
+        _2 = &((*_1).0: alloc::raw_vec::RawVec<u8>);
+        StorageLive(_3);
+        _3 = ((((*_1).0: alloc::raw_vec::RawVec<u8>).0: std::ptr::Unique<u8>).0: std::ptr::NonNull<u8>);
+        _4 = (_3.0: *const u8);
+        StorageDead(_3);
+        StorageDead(_2);
+        StorageLive(_5);
+        _5 = ((*_1).1: usize);
+        StorageLive(_6);
+        _6 = _4 as *const () (PtrToPtr);
+        _7 = *const [u8] from (_6, _5);
+        StorageDead(_6);
+        StorageDead(_5);
+        StorageDead(_4);
+        _0 = &(*_7);
         return;
     }
 }

From 9520cebfc50947f04280a6dbf288dfb5475c1637 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Sun, 14 Apr 2024 11:12:32 -0700
Subject: [PATCH 10/15] =?UTF-8?q?InstSimplify=20`from=5Fraw=5Fparts(p,=20(?=
 =?UTF-8?q?))`=20=E2=86=92=20`p=20as=20=5F`?=
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

---
 .../rustc_mir_transform/src/instsimplify.rs   | 36 ++++++++++++++++++-
 tests/mir-opt/instsimplify/casts.rs           |  9 +++++
 ...e_add_fat.PreCodegen.after.panic-abort.mir | 10 +-----
 ..._add_fat.PreCodegen.after.panic-unwind.mir | 10 +-----
 ..._add_thin.PreCodegen.after.panic-abort.mir | 12 +------
 ...add_thin.PreCodegen.after.panic-unwind.mir | 12 +------
 6 files changed, 48 insertions(+), 41 deletions(-)

diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index ff786d44d6a..bae959963b5 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -36,6 +36,7 @@ impl<'tcx> MirPass<'tcx> for InstSimplify {
                         ctx.simplify_bool_cmp(&statement.source_info, rvalue);
                         ctx.simplify_ref_deref(&statement.source_info, rvalue);
                         ctx.simplify_len(&statement.source_info, rvalue);
+                        ctx.simplify_ptr_aggregate(&statement.source_info, rvalue);
                         ctx.simplify_cast(rvalue);
                     }
                     _ => {}
@@ -58,8 +59,17 @@ struct InstSimplifyContext<'tcx, 'a> {
 
 impl<'tcx> InstSimplifyContext<'tcx, '_> {
     fn should_simplify(&self, source_info: &SourceInfo, rvalue: &Rvalue<'tcx>) -> bool {
+        self.should_simplify_custom(source_info, "Rvalue", rvalue)
+    }
+
+    fn should_simplify_custom(
+        &self,
+        source_info: &SourceInfo,
+        label: &str,
+        value: impl std::fmt::Debug,
+    ) -> bool {
         self.tcx.consider_optimizing(|| {
-            format!("InstSimplify - Rvalue: {rvalue:?} SourceInfo: {source_info:?}")
+            format!("InstSimplify - {label}: {value:?} SourceInfo: {source_info:?}")
         })
     }
 
@@ -147,6 +157,30 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
         }
     }
 
+    /// Transform "Aggregate(RawPtr, \[p, ()\])" ==> "Cast(PtrToPtr, p)".
+    fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
+        if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
+        {
+            let meta_ty = fields.raw[1].ty(self.local_decls, self.tcx);
+            if meta_ty.is_unit() {
+                // The mutable borrows we're holding prevent printing `rvalue` here
+                if !self.should_simplify_custom(
+                    source_info,
+                    "Aggregate::RawPtr",
+                    (&pointee_ty, *mutability, &fields),
+                ) {
+                    return;
+                }
+
+                let mut fields = std::mem::take(fields);
+                let _meta = fields.pop().unwrap();
+                let data = fields.pop().unwrap();
+                let ptr_ty = Ty::new_ptr(self.tcx, *pointee_ty, *mutability);
+                *rvalue = Rvalue::Cast(CastKind::PtrToPtr, data, ptr_ty);
+            }
+        }
+    }
+
     fn simplify_ub_check(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::NullaryOp(NullOp::UbChecks, _) = *rvalue {
             let const_ = Const::from_bool(self.tcx, self.tcx.sess.ub_checks());
diff --git a/tests/mir-opt/instsimplify/casts.rs b/tests/mir-opt/instsimplify/casts.rs
index b3bc34af5b7..a7786fa570f 100644
--- a/tests/mir-opt/instsimplify/casts.rs
+++ b/tests/mir-opt/instsimplify/casts.rs
@@ -1,6 +1,7 @@
 //@ test-mir-pass: InstSimplify
 //@ compile-flags: -Zinline-mir
 #![crate_type = "lib"]
+#![feature(core_intrinsics)]
 
 #[inline(always)]
 fn generic_cast<T, U>(x: *const T) -> *const U {
@@ -23,3 +24,11 @@ pub fn roundtrip(x: *const u8) -> *const u8 {
     // CHECK: _2 = move _3 as *const u8 (PointerCoercion(MutToConstPointer));
     x as *mut u8 as *const u8
 }
+
+// EMIT_MIR casts.roundtrip.InstSimplify.diff
+pub fn cast_thin_via_aggregate(x: *const u8) -> *const () {
+    // CHECK-LABEL: fn cast_thin_via_aggregate(
+    // CHECK: _2 = _1;
+    // CHECK: _0 = move _2 as *const () (PtrToPtr);
+    std::intrinsics::aggregate_raw_ptr(x, ())
+}
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
index 81474306eec..37f50d25fc8 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
@@ -28,8 +28,6 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
             scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
                 debug data_pointer => _5;
                 debug metadata => _7;
-                let mut _8: std::ptr::metadata::PtrComponents<[u32]>;
-                let mut _9: std::ptr::metadata::PtrRepr<[u32]>;
             }
         }
     }
@@ -47,13 +45,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
         _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
         _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
         StorageDead(_6);
-        StorageLive(_9);
-        StorageLive(_8);
-        _8 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: _5, metadata: _7 };
-        _9 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _8 };
-        StorageDead(_8);
-        _0 = (_9.0: *const [u32]);
-        StorageDead(_9);
+        _0 = *const [u32] from (_5, _7);
         StorageDead(_7);
         StorageDead(_5);
         StorageDead(_4);
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
index 81474306eec..37f50d25fc8 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
@@ -28,8 +28,6 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
             scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
                 debug data_pointer => _5;
                 debug metadata => _7;
-                let mut _8: std::ptr::metadata::PtrComponents<[u32]>;
-                let mut _9: std::ptr::metadata::PtrRepr<[u32]>;
             }
         }
     }
@@ -47,13 +45,7 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
         _6 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: _1 };
         _7 = ((_6.2: std::ptr::metadata::PtrComponents<[u32]>).1: usize);
         StorageDead(_6);
-        StorageLive(_9);
-        StorageLive(_8);
-        _8 = std::ptr::metadata::PtrComponents::<[u32]> { data_pointer: _5, metadata: _7 };
-        _9 = std::ptr::metadata::PtrRepr::<[u32]> { const_ptr: move _8 };
-        StorageDead(_8);
-        _0 = (_9.0: *const [u32]);
-        StorageDead(_9);
+        _0 = *const [u32] from (_5, _7);
         StorageDead(_7);
         StorageDead(_5);
         StorageDead(_4);
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
index d86f2d1106a..9551f30c7e9 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
@@ -26,29 +26,19 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
             scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
                 debug data_pointer => _5;
                 debug metadata => const ();
-                let mut _6: std::ptr::metadata::PtrComponents<u32>;
-                let mut _7: std::ptr::metadata::PtrRepr<u32>;
             }
         }
     }
 
     bb0: {
-        StorageLive(_4);
         StorageLive(_3);
         _3 = _1 as *const u8 (PtrToPtr);
         _4 = Offset(_3, _2);
         StorageDead(_3);
         StorageLive(_5);
         _5 = _4 as *const () (PtrToPtr);
-        StorageLive(_7);
-        StorageLive(_6);
-        _6 = std::ptr::metadata::PtrComponents::<u32> { data_pointer: _5, metadata: const () };
-        _7 = std::ptr::metadata::PtrRepr::<u32> { const_ptr: move _6 };
-        StorageDead(_6);
-        _0 = (_7.0: *const u32);
-        StorageDead(_7);
+        _0 = _4 as *const u32 (PtrToPtr);
         StorageDead(_5);
-        StorageDead(_4);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
index d86f2d1106a..9551f30c7e9 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
@@ -26,29 +26,19 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
             scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
                 debug data_pointer => _5;
                 debug metadata => const ();
-                let mut _6: std::ptr::metadata::PtrComponents<u32>;
-                let mut _7: std::ptr::metadata::PtrRepr<u32>;
             }
         }
     }
 
     bb0: {
-        StorageLive(_4);
         StorageLive(_3);
         _3 = _1 as *const u8 (PtrToPtr);
         _4 = Offset(_3, _2);
         StorageDead(_3);
         StorageLive(_5);
         _5 = _4 as *const () (PtrToPtr);
-        StorageLive(_7);
-        StorageLive(_6);
-        _6 = std::ptr::metadata::PtrComponents::<u32> { data_pointer: _5, metadata: const () };
-        _7 = std::ptr::metadata::PtrRepr::<u32> { const_ptr: move _6 };
-        StorageDead(_6);
-        _0 = (_7.0: *const u32);
-        StorageDead(_7);
+        _0 = _4 as *const u32 (PtrToPtr);
         StorageDead(_5);
-        StorageDead(_4);
         return;
     }
 }

From 5e1d16ca5515ae2134b69c68e7b05f6fead90f06 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Thu, 11 Apr 2024 21:45:05 -0700
Subject: [PATCH 11/15] Also handle AggregateKind::RawPtr in cg_cranelift

---
 compiler/rustc_codegen_cranelift/src/base.rs    | 13 +++++++++++++
 .../src/value_and_place.rs                      | 17 +++++++++++++++++
 2 files changed, 30 insertions(+)

diff --git a/compiler/rustc_codegen_cranelift/src/base.rs b/compiler/rustc_codegen_cranelift/src/base.rs
index f07421431da..f428c4c7c0d 100644
--- a/compiler/rustc_codegen_cranelift/src/base.rs
+++ b/compiler/rustc_codegen_cranelift/src/base.rs
@@ -813,6 +813,19 @@ fn codegen_stmt<'tcx>(
                     );
                     lval.write_cvalue(fx, val);
                 }
+                Rvalue::Aggregate(ref kind, ref operands)
+                    if matches!(**kind, AggregateKind::RawPtr(..)) =>
+                {
+                    let ty = to_place_and_rval.1.ty(&fx.mir.local_decls, fx.tcx);
+                    let layout = fx.layout_of(fx.monomorphize(ty));
+                    let [data, meta] = &*operands.raw else {
+                        bug!("RawPtr fields: {operands:?}");
+                    };
+                    let data = codegen_operand(fx, data);
+                    let meta = codegen_operand(fx, meta);
+                    let ptr_val = CValue::pointer_from_data_and_meta(data, meta, layout);
+                    lval.write_cvalue(fx, ptr_val);
+                }
                 Rvalue::Aggregate(ref kind, ref operands) => {
                     let (variant_index, variant_dest, active_field_index) = match **kind {
                         mir::AggregateKind::Adt(_, variant_index, _, _, active_field_index) => {
diff --git a/compiler/rustc_codegen_cranelift/src/value_and_place.rs b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
index ad863903cee..8d52fd9d7a8 100644
--- a/compiler/rustc_codegen_cranelift/src/value_and_place.rs
+++ b/compiler/rustc_codegen_cranelift/src/value_and_place.rs
@@ -94,6 +94,23 @@ impl<'tcx> CValue<'tcx> {
         CValue(CValueInner::ByValPair(value, extra), layout)
     }
 
+    /// For `AggregateKind::RawPtr`, create a pointer from its parts.
+    ///
+    /// Panics if the `layout` is not a raw pointer.
+    pub(crate) fn pointer_from_data_and_meta(
+        data: CValue<'tcx>,
+        meta: CValue<'tcx>,
+        layout: TyAndLayout<'tcx>,
+    ) -> CValue<'tcx> {
+        assert!(layout.ty.is_unsafe_ptr());
+        let inner = match (data.0, meta.0) {
+            (CValueInner::ByVal(p), CValueInner::ByVal(m)) => CValueInner::ByValPair(p, m),
+            (p @ CValueInner::ByVal(_), CValueInner::ByRef(..)) if meta.1.is_zst() => p,
+            _ => bug!("RawPtr operands {data:?} {meta:?}"),
+        };
+        CValue(inner, layout)
+    }
+
     pub(crate) fn layout(&self) -> TyAndLayout<'tcx> {
         self.1
     }

From bb8d6f790b63797a816a4007e8ab002ed2906de7 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Fri, 12 Apr 2024 10:43:51 -0700
Subject: [PATCH 12/15] Address PR feedback

---
 .../rustc_const_eval/src/interpret/operand.rs    | 11 -----------
 compiler/rustc_const_eval/src/interpret/step.rs  | 16 ++++++++++++----
 2 files changed, 12 insertions(+), 15 deletions(-)

diff --git a/compiler/rustc_const_eval/src/interpret/operand.rs b/compiler/rustc_const_eval/src/interpret/operand.rs
index d4a6dab9ac3..718c91b2f76 100644
--- a/compiler/rustc_const_eval/src/interpret/operand.rs
+++ b/compiler/rustc_const_eval/src/interpret/operand.rs
@@ -603,17 +603,6 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
         Ok(self.read_immediate(op)?.to_scalar())
     }
 
-    pub fn read_mem_place_meta(
-        &self,
-        op: &impl Readable<'tcx, M::Provenance>,
-    ) -> InterpResult<'tcx, MemPlaceMeta<M::Provenance>> {
-        Ok(if op.layout().is_zst() {
-            MemPlaceMeta::None
-        } else {
-            MemPlaceMeta::Meta(self.read_scalar(op)?)
-        })
-    }
-
     // Pointer-sized reads are fairly common and need target layout access, so we wrap them in
     // convenience functions.
 
diff --git a/compiler/rustc_const_eval/src/interpret/step.rs b/compiler/rustc_const_eval/src/interpret/step.rs
index 460cd377c8f..b29034e991e 100644
--- a/compiler/rustc_const_eval/src/interpret/step.rs
+++ b/compiler/rustc_const_eval/src/interpret/step.rs
@@ -9,7 +9,9 @@ use rustc_middle::mir;
 use rustc_middle::ty::layout::LayoutOf;
 use rustc_target::abi::{FieldIdx, FIRST_VARIANT};
 
-use super::{ImmTy, Immediate, InterpCx, InterpResult, Machine, PlaceTy, Projectable, Scalar};
+use super::{
+    ImmTy, Immediate, InterpCx, InterpResult, Machine, MemPlaceMeta, PlaceTy, Projectable, Scalar,
+};
 use crate::util;
 
 impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
@@ -304,15 +306,21 @@ impl<'mir, 'tcx: 'mir, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
                 (variant_index, variant_dest, active_field_index)
             }
             mir::AggregateKind::RawPtr(..) => {
-                // Trying to `project_field` into pointers tends not to work,
-                // so build the `Immediate` from the parts directly.
+                // Pointers don't have "fields" in the normal sense, so the
+                // projection-based code below would either fail in projection
+                // or in type mismatches. Instead, build an `Immediate` from
+                // the parts and write that to the destination.
                 let [data, meta] = &operands.raw else {
                     bug!("{kind:?} should have 2 operands, had {operands:?}");
                 };
                 let data = self.eval_operand(data, None)?;
                 let data = self.read_pointer(&data)?;
                 let meta = self.eval_operand(meta, None)?;
-                let meta = self.read_mem_place_meta(&meta)?;
+                let meta = if meta.layout.is_zst() {
+                    MemPlaceMeta::None
+                } else {
+                    MemPlaceMeta::Meta(self.read_scalar(&meta)?)
+                };
                 let ptr_imm = Immediate::new_pointer_with_meta(data, meta, self);
                 let ptr = ImmTy::from_immediate(ptr_imm, dest.layout);
                 self.copy_op(&ptr, dest)?;

From 1398fe7a5e91992bd8887496f066370ba48d7278 Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Tue, 16 Apr 2024 23:55:12 -0700
Subject: [PATCH 13/15] Address more PR feedback

---
 compiler/rustc_mir_transform/src/instsimplify.rs | 6 +++---
 library/core/src/intrinsics.rs                   | 3 ++-
 2 files changed, 5 insertions(+), 4 deletions(-)

diff --git a/compiler/rustc_mir_transform/src/instsimplify.rs b/compiler/rustc_mir_transform/src/instsimplify.rs
index bae959963b5..fd768cc96ae 100644
--- a/compiler/rustc_mir_transform/src/instsimplify.rs
+++ b/compiler/rustc_mir_transform/src/instsimplify.rs
@@ -121,7 +121,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
         if a.const_.ty().is_bool() { a.const_.try_to_bool() } else { None }
     }
 
-    /// Transform "&(*a)" ==> "a".
+    /// Transform `&(*a)` ==> `a`.
     fn simplify_ref_deref(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Ref(_, _, place) = rvalue {
             if let Some((base, ProjectionElem::Deref)) = place.as_ref().last_projection() {
@@ -141,7 +141,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
         }
     }
 
-    /// Transform "Len([_; N])" ==> "N".
+    /// Transform `Len([_; N])` ==> `N`.
     fn simplify_len(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Len(ref place) = *rvalue {
             let place_ty = place.ty(self.local_decls, self.tcx).ty;
@@ -157,7 +157,7 @@ impl<'tcx> InstSimplifyContext<'tcx, '_> {
         }
     }
 
-    /// Transform "Aggregate(RawPtr, \[p, ()\])" ==> "Cast(PtrToPtr, p)".
+    /// Transform `Aggregate(RawPtr, [p, ()])` ==> `Cast(PtrToPtr, p)`.
     fn simplify_ptr_aggregate(&self, source_info: &SourceInfo, rvalue: &mut Rvalue<'tcx>) {
         if let Rvalue::Aggregate(box AggregateKind::RawPtr(pointee_ty, mutability), fields) = rvalue
         {
diff --git a/library/core/src/intrinsics.rs b/library/core/src/intrinsics.rs
index 751f2210d0c..92f1bd27408 100644
--- a/library/core/src/intrinsics.rs
+++ b/library/core/src/intrinsics.rs
@@ -2791,7 +2791,8 @@ pub unsafe fn vtable_align(_ptr: *const ()) -> usize {
 #[rustc_intrinsic_must_be_overridden]
 #[cfg(not(bootstrap))]
 pub const fn aggregate_raw_ptr<P: AggregateRawPtr<D, Metadata = M>, D, M>(_data: D, _meta: M) -> P {
-    // No fallback because `libcore` doesn't want to know the layout
+    // To implement a fallback we'd have to assume the layout of the pointer,
+    // but the whole point of this intrinsic is that we shouldn't do that.
     unreachable!()
 }
 

From 5e785b1420d8d26f360a33919700868c877cbbbc Mon Sep 17 00:00:00 2001
From: Scott McMurray <scottmcm@users.noreply.github.com>
Date: Sun, 21 Apr 2024 11:24:54 -0700
Subject: [PATCH 14/15] Update tests after 123949

---
 ...yte_add_fat.PreCodegen.after.panic-abort.mir | 10 ----------
 ...te_add_fat.PreCodegen.after.panic-unwind.mir | 10 ----------
 ...te_add_thin.PreCodegen.after.panic-abort.mir | 14 --------------
 ...e_add_thin.PreCodegen.after.panic-unwind.mir | 14 --------------
 ...ecked_range.PreCodegen.after.panic-abort.mir | 17 -----------------
 ...cked_range.PreCodegen.after.panic-unwind.mir | 17 -----------------
 6 files changed, 82 deletions(-)

diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
index 37f50d25fc8..db0c84bd560 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-abort.mir
@@ -5,29 +5,19 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
     debug n => _2;
     let mut _0: *const [u32];
     scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::byte_add) {
-        debug self => _1;
-        debug count => _2;
         let mut _3: *const u8;
         let mut _4: *const u8;
         scope 2 (inlined std::ptr::const_ptr::<impl *const [u32]>::cast::<u8>) {
-            debug self => _1;
         }
         scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
-            debug self => _3;
-            debug count => _2;
         }
         scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
-            debug self => _4;
-            debug meta => _1;
             let mut _5: *const ();
             let mut _7: usize;
             scope 5 (inlined std::ptr::metadata::<[u32]>) {
-                debug ptr => _1;
                 let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
             }
             scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
-                debug data_pointer => _5;
-                debug metadata => _7;
             }
         }
     }
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
index 37f50d25fc8..db0c84bd560 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_fat.PreCodegen.after.panic-unwind.mir
@@ -5,29 +5,19 @@ fn demo_byte_add_fat(_1: *const [u32], _2: usize) -> *const [u32] {
     debug n => _2;
     let mut _0: *const [u32];
     scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::byte_add) {
-        debug self => _1;
-        debug count => _2;
         let mut _3: *const u8;
         let mut _4: *const u8;
         scope 2 (inlined std::ptr::const_ptr::<impl *const [u32]>::cast::<u8>) {
-            debug self => _1;
         }
         scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
-            debug self => _3;
-            debug count => _2;
         }
         scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<[u32]>) {
-            debug self => _4;
-            debug meta => _1;
             let mut _5: *const ();
             let mut _7: usize;
             scope 5 (inlined std::ptr::metadata::<[u32]>) {
-                debug ptr => _1;
                 let mut _6: std::ptr::metadata::PtrRepr<[u32]>;
             }
             scope 6 (inlined std::ptr::from_raw_parts::<[u32]>) {
-                debug data_pointer => _5;
-                debug metadata => _7;
             }
         }
     }
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
index 9551f30c7e9..766bd29ef41 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-abort.mir
@@ -5,27 +5,16 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
     debug n => _2;
     let mut _0: *const u32;
     scope 1 (inlined std::ptr::const_ptr::<impl *const u32>::byte_add) {
-        debug self => _1;
-        debug count => _2;
         let mut _3: *const u8;
         let mut _4: *const u8;
         scope 2 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<u8>) {
-            debug self => _1;
         }
         scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
-            debug self => _3;
-            debug count => _2;
         }
         scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
-            debug self => _4;
-            debug meta => _1;
-            let mut _5: *const ();
             scope 5 (inlined std::ptr::metadata::<u32>) {
-                debug ptr => _1;
             }
             scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
-                debug data_pointer => _5;
-                debug metadata => const ();
             }
         }
     }
@@ -35,10 +24,7 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
         _3 = _1 as *const u8 (PtrToPtr);
         _4 = Offset(_3, _2);
         StorageDead(_3);
-        StorageLive(_5);
-        _5 = _4 as *const () (PtrToPtr);
         _0 = _4 as *const u32 (PtrToPtr);
-        StorageDead(_5);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
index 9551f30c7e9..766bd29ef41 100644
--- a/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/ptr_offset.demo_byte_add_thin.PreCodegen.after.panic-unwind.mir
@@ -5,27 +5,16 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
     debug n => _2;
     let mut _0: *const u32;
     scope 1 (inlined std::ptr::const_ptr::<impl *const u32>::byte_add) {
-        debug self => _1;
-        debug count => _2;
         let mut _3: *const u8;
         let mut _4: *const u8;
         scope 2 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<u8>) {
-            debug self => _1;
         }
         scope 3 (inlined std::ptr::const_ptr::<impl *const u8>::add) {
-            debug self => _3;
-            debug count => _2;
         }
         scope 4 (inlined std::ptr::const_ptr::<impl *const u8>::with_metadata_of::<u32>) {
-            debug self => _4;
-            debug meta => _1;
-            let mut _5: *const ();
             scope 5 (inlined std::ptr::metadata::<u32>) {
-                debug ptr => _1;
             }
             scope 6 (inlined std::ptr::from_raw_parts::<u32>) {
-                debug data_pointer => _5;
-                debug metadata => const ();
             }
         }
     }
@@ -35,10 +24,7 @@ fn demo_byte_add_thin(_1: *const u32, _2: usize) -> *const u32 {
         _3 = _1 as *const u8 (PtrToPtr);
         _4 = Offset(_3, _2);
         StorageDead(_3);
-        StorageLive(_5);
-        _5 = _4 as *const () (PtrToPtr);
         _0 = _4 as *const u32 (PtrToPtr);
-        StorageDead(_5);
         return;
     }
 }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
index 8446324c663..018ff6c357d 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-abort.mir
@@ -7,42 +7,25 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
     let mut _3: usize;
     let mut _4: usize;
     scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
-        debug self => _1;
-        debug ((index: std::ops::Range<usize>).0: usize) => _3;
-        debug ((index: std::ops::Range<usize>).1: usize) => _4;
         scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) {
-            debug ((self: std::ops::Range<usize>).0: usize) => _3;
-            debug ((self: std::ops::Range<usize>).1: usize) => _4;
-            debug slice => _1;
             let _5: usize;
             let mut _6: *const u32;
             let mut _7: *const u32;
             scope 3 {
-                debug new_len => _5;
                 scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) {
-                    debug self => _1;
                 }
                 scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) {
-                    debug self => _6;
-                    debug count => _3;
                 }
                 scope 8 (inlined slice_from_raw_parts::<u32>) {
-                    debug data => _7;
-                    debug len => _5;
                     let mut _8: *const ();
                     scope 9 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<()>) {
-                        debug self => _7;
                     }
                     scope 10 (inlined std::ptr::from_raw_parts::<[u32]>) {
-                        debug data_pointer => _8;
-                        debug metadata => _5;
                     }
                 }
             }
             scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) {
-                debug self => _1;
                 scope 5 (inlined std::ptr::metadata::<[u32]>) {
-                    debug ptr => _1;
                 }
             }
         }
diff --git a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
index 8446324c663..018ff6c357d 100644
--- a/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
+++ b/tests/mir-opt/pre-codegen/slice_index.slice_ptr_get_unchecked_range.PreCodegen.after.panic-unwind.mir
@@ -7,42 +7,25 @@ fn slice_ptr_get_unchecked_range(_1: *const [u32], _2: std::ops::Range<usize>) -
     let mut _3: usize;
     let mut _4: usize;
     scope 1 (inlined std::ptr::const_ptr::<impl *const [u32]>::get_unchecked::<std::ops::Range<usize>>) {
-        debug self => _1;
-        debug ((index: std::ops::Range<usize>).0: usize) => _3;
-        debug ((index: std::ops::Range<usize>).1: usize) => _4;
         scope 2 (inlined <std::ops::Range<usize> as SliceIndex<[u32]>>::get_unchecked) {
-            debug ((self: std::ops::Range<usize>).0: usize) => _3;
-            debug ((self: std::ops::Range<usize>).1: usize) => _4;
-            debug slice => _1;
             let _5: usize;
             let mut _6: *const u32;
             let mut _7: *const u32;
             scope 3 {
-                debug new_len => _5;
                 scope 6 (inlined std::ptr::const_ptr::<impl *const [u32]>::as_ptr) {
-                    debug self => _1;
                 }
                 scope 7 (inlined std::ptr::const_ptr::<impl *const u32>::add) {
-                    debug self => _6;
-                    debug count => _3;
                 }
                 scope 8 (inlined slice_from_raw_parts::<u32>) {
-                    debug data => _7;
-                    debug len => _5;
                     let mut _8: *const ();
                     scope 9 (inlined std::ptr::const_ptr::<impl *const u32>::cast::<()>) {
-                        debug self => _7;
                     }
                     scope 10 (inlined std::ptr::from_raw_parts::<[u32]>) {
-                        debug data_pointer => _8;
-                        debug metadata => _5;
                     }
                 }
             }
             scope 4 (inlined std::ptr::const_ptr::<impl *const [u32]>::len) {
-                debug self => _1;
                 scope 5 (inlined std::ptr::metadata::<[u32]>) {
-                    debug ptr => _1;
                 }
             }
         }

From 3aaa3941fd62fb4aeea559eafe8a6aa6472eb87d Mon Sep 17 00:00:00 2001
From: Caio <c410.f3r@gmail.com>
Date: Sun, 21 Apr 2024 15:43:43 -0300
Subject: [PATCH 15/15] Move some tests

---
 src/tools/tidy/src/issues.txt                 | 68 +++++++++----------
 src/tools/tidy/src/ui_tests.rs                |  2 +-
 .../issue-19129-1.rs                          |  0
 .../issue-19129-2.rs                          |  0
 .../issue-20763-1.rs                          |  0
 .../issue-20763-2.rs                          |  0
 .../issue-40402-1.rs                          |  0
 .../issue-40402-1.stderr                      |  0
 .../issue-40402-2.rs                          |  0
 .../issue-40402-2.stderr                      |  0
 .../ui/{issues => closures}/issue-22864-1.rs  |  0
 .../ui/{issues => closures}/issue-22864-2.rs  |  0
 tests/ui/{issues => closures}/issue-5239-1.rs |  0
 .../{issues => closures}/issue-5239-1.stderr  |  0
 tests/ui/{issues => closures}/issue-5239-2.rs |  0
 .../issue-32122-1.fixed                       |  0
 .../issue-32122-1.rs                          |  0
 .../issue-32122-1.stderr                      |  0
 .../issue-32122-2.fixed                       |  0
 .../issue-32122-2.rs                          |  0
 .../issue-32122-2.stderr                      |  0
 tests/ui/{issues => consts}/issue-19244-1.rs  |  0
 .../{issues => consts}/issue-19244-1.stderr   |  0
 tests/ui/{issues => consts}/issue-19244-2.rs  |  0
 .../{issues => consts}/issue-19244-2.stderr   |  0
 .../issue-71676-1.fixed                       |  0
 .../issue-71676-1.rs                          |  0
 .../issue-71676-1.stderr                      |  0
 .../issue-71676-2.rs                          |  0
 .../issue-71676-2.stderr                      |  0
 .../auxiliary/issue-19340-1.rs                |  0
 tests/ui/{issues => enum}/issue-19340-1.rs    |  0
 tests/ui/{issues => enum}/issue-19340-2.rs    |  0
 tests/ui/{issues => enum}/issue-23304-1.rs    |  0
 tests/ui/{issues => enum}/issue-23304-2.rs    |  0
 tests/ui/{issues => expr}/issue-22933-1.rs    |  0
 tests/ui/{issues => expr}/issue-22933-2.rs    |  0
 .../ui/{issues => expr}/issue-22933-2.stderr  |  0
 tests/ui/{issues => macros}/issue-11692-1.rs  |  0
 .../{issues => macros}/issue-11692-1.stderr   |  0
 tests/ui/{issues => macros}/issue-11692-2.rs  |  0
 .../{issues => macros}/issue-11692-2.stderr   |  0
 tests/ui/{issues => nll}/issue-57362-1.rs     |  0
 tests/ui/{issues => nll}/issue-57362-1.stderr |  0
 tests/ui/{issues => nll}/issue-57362-2.rs     |  0
 tests/ui/{issues => nll}/issue-57362-2.stderr |  0
 tests/ui/{issues => parser}/issue-12187-1.rs  |  0
 .../{issues => parser}/issue-12187-1.stderr   |  0
 tests/ui/{issues => parser}/issue-12187-2.rs  |  0
 .../{issues => parser}/issue-12187-2.stderr   |  0
 .../ui/{issues => recursion}/issue-23122-1.rs |  0
 .../issue-23122-1.stderr                      |  0
 .../ui/{issues => recursion}/issue-23122-2.rs |  0
 .../issue-23122-2.stderr                      |  0
 tests/ui/{issues => resolve}/issue-3214.rs    |  0
 .../ui/{issues => resolve}/issue-3214.stderr  |  0
 tests/ui/{issues => type}/issue-7607-1.rs     |  0
 tests/ui/{issues => type}/issue-7607-1.stderr |  0
 tests/ui/{issues => type}/issue-7607-2.rs     |  0
 59 files changed, 35 insertions(+), 35 deletions(-)
 rename tests/ui/{issues => associated-types}/issue-19129-1.rs (100%)
 rename tests/ui/{issues => associated-types}/issue-19129-2.rs (100%)
 rename tests/ui/{issues => associated-types}/issue-20763-1.rs (100%)
 rename tests/ui/{issues => associated-types}/issue-20763-2.rs (100%)
 rename tests/ui/{issues/issue-40402-ref-hints => binding}/issue-40402-1.rs (100%)
 rename tests/ui/{issues/issue-40402-ref-hints => binding}/issue-40402-1.stderr (100%)
 rename tests/ui/{issues/issue-40402-ref-hints => binding}/issue-40402-2.rs (100%)
 rename tests/ui/{issues/issue-40402-ref-hints => binding}/issue-40402-2.stderr (100%)
 rename tests/ui/{issues => closures}/issue-22864-1.rs (100%)
 rename tests/ui/{issues => closures}/issue-22864-2.rs (100%)
 rename tests/ui/{issues => closures}/issue-5239-1.rs (100%)
 rename tests/ui/{issues => closures}/issue-5239-1.stderr (100%)
 rename tests/ui/{issues => closures}/issue-5239-2.rs (100%)
 rename tests/ui/{issues/issue-32122-deref-coercions-composition => coercion}/issue-32122-1.fixed (100%)
 rename tests/ui/{issues/issue-32122-deref-coercions-composition => coercion}/issue-32122-1.rs (100%)
 rename tests/ui/{issues/issue-32122-deref-coercions-composition => coercion}/issue-32122-1.stderr (100%)
 rename tests/ui/{issues/issue-32122-deref-coercions-composition => coercion}/issue-32122-2.fixed (100%)
 rename tests/ui/{issues/issue-32122-deref-coercions-composition => coercion}/issue-32122-2.rs (100%)
 rename tests/ui/{issues/issue-32122-deref-coercions-composition => coercion}/issue-32122-2.stderr (100%)
 rename tests/ui/{issues => consts}/issue-19244-1.rs (100%)
 rename tests/ui/{issues => consts}/issue-19244-1.stderr (100%)
 rename tests/ui/{issues => consts}/issue-19244-2.rs (100%)
 rename tests/ui/{issues => consts}/issue-19244-2.stderr (100%)
 rename tests/ui/{issues/issue-71676-suggest-deref => deref-patterns}/issue-71676-1.fixed (100%)
 rename tests/ui/{issues/issue-71676-suggest-deref => deref-patterns}/issue-71676-1.rs (100%)
 rename tests/ui/{issues/issue-71676-suggest-deref => deref-patterns}/issue-71676-1.stderr (100%)
 rename tests/ui/{issues/issue-71676-suggest-deref => deref-patterns}/issue-71676-2.rs (100%)
 rename tests/ui/{issues/issue-71676-suggest-deref => deref-patterns}/issue-71676-2.stderr (100%)
 rename tests/ui/{issues => enum}/auxiliary/issue-19340-1.rs (100%)
 rename tests/ui/{issues => enum}/issue-19340-1.rs (100%)
 rename tests/ui/{issues => enum}/issue-19340-2.rs (100%)
 rename tests/ui/{issues => enum}/issue-23304-1.rs (100%)
 rename tests/ui/{issues => enum}/issue-23304-2.rs (100%)
 rename tests/ui/{issues => expr}/issue-22933-1.rs (100%)
 rename tests/ui/{issues => expr}/issue-22933-2.rs (100%)
 rename tests/ui/{issues => expr}/issue-22933-2.stderr (100%)
 rename tests/ui/{issues => macros}/issue-11692-1.rs (100%)
 rename tests/ui/{issues => macros}/issue-11692-1.stderr (100%)
 rename tests/ui/{issues => macros}/issue-11692-2.rs (100%)
 rename tests/ui/{issues => macros}/issue-11692-2.stderr (100%)
 rename tests/ui/{issues => nll}/issue-57362-1.rs (100%)
 rename tests/ui/{issues => nll}/issue-57362-1.stderr (100%)
 rename tests/ui/{issues => nll}/issue-57362-2.rs (100%)
 rename tests/ui/{issues => nll}/issue-57362-2.stderr (100%)
 rename tests/ui/{issues => parser}/issue-12187-1.rs (100%)
 rename tests/ui/{issues => parser}/issue-12187-1.stderr (100%)
 rename tests/ui/{issues => parser}/issue-12187-2.rs (100%)
 rename tests/ui/{issues => parser}/issue-12187-2.stderr (100%)
 rename tests/ui/{issues => recursion}/issue-23122-1.rs (100%)
 rename tests/ui/{issues => recursion}/issue-23122-1.stderr (100%)
 rename tests/ui/{issues => recursion}/issue-23122-2.rs (100%)
 rename tests/ui/{issues => recursion}/issue-23122-2.stderr (100%)
 rename tests/ui/{issues => resolve}/issue-3214.rs (100%)
 rename tests/ui/{issues => resolve}/issue-3214.stderr (100%)
 rename tests/ui/{issues => type}/issue-7607-1.rs (100%)
 rename tests/ui/{issues => type}/issue-7607-1.stderr (100%)
 rename tests/ui/{issues => type}/issue-7607-2.rs (100%)

diff --git a/src/tools/tidy/src/issues.txt b/src/tools/tidy/src/issues.txt
index 211dc347b0f..dff15265fae 100644
--- a/src/tools/tidy/src/issues.txt
+++ b/src/tools/tidy/src/issues.txt
@@ -74,8 +74,12 @@ ui/associated-type-bounds/issue-99828.rs
 ui/associated-type-bounds/return-type-notation/issue-120208-higher-ranked-const.rs
 ui/associated-types/issue-18655.rs
 ui/associated-types/issue-19081.rs
+ui/associated-types/issue-19129-1.rs
+ui/associated-types/issue-19129-2.rs
 ui/associated-types/issue-19883.rs
 ui/associated-types/issue-20005.rs
+ui/associated-types/issue-20763-1.rs
+ui/associated-types/issue-20763-2.rs
 ui/associated-types/issue-20825-2.rs
 ui/associated-types/issue-20825.rs
 ui/associated-types/issue-21363.rs
@@ -281,6 +285,8 @@ ui/auxiliary/issue-18502.rs
 ui/auxiliary/issue-24106.rs
 ui/auxiliary/issue-76387.rs
 ui/bench/issue-32062.rs
+ui/binding/issue-40402-1.rs
+ui/binding/issue-40402-2.rs
 ui/binding/issue-53114-borrow-checks.rs
 ui/binding/issue-53114-safety-checks.rs
 ui/binop/issue-25916.rs
@@ -431,12 +437,16 @@ ui/closures/issue-111932.rs
 ui/closures/issue-113087.rs
 ui/closures/issue-11873.rs
 ui/closures/issue-1460.rs
+ui/closures/issue-22864-1.rs
+ui/closures/issue-22864-2.rs
 ui/closures/issue-23012-supertrait-signature-inference.rs
 ui/closures/issue-25439.rs
 ui/closures/issue-41366.rs
 ui/closures/issue-42463.rs
 ui/closures/issue-46742.rs
 ui/closures/issue-48109.rs
+ui/closures/issue-5239-1.rs
+ui/closures/issue-5239-2.rs
 ui/closures/issue-52437.rs
 ui/closures/issue-67123.rs
 ui/closures/issue-6801.rs
@@ -482,6 +492,8 @@ ui/coercion/issue-101066.rs
 ui/coercion/issue-14589.rs
 ui/coercion/issue-26905-rpass.rs
 ui/coercion/issue-26905.rs
+ui/coercion/issue-32122-1.rs
+ui/coercion/issue-32122-2.rs
 ui/coercion/issue-36007.rs
 ui/coercion/issue-37655.rs
 ui/coercion/issue-3794.rs
@@ -721,6 +733,8 @@ ui/consts/issue-17718-references.rs
 ui/consts/issue-17718.rs
 ui/consts/issue-17756.rs
 ui/consts/issue-18294.rs
+ui/consts/issue-19244-1.rs
+ui/consts/issue-19244-2.rs
 ui/consts/issue-19244.rs
 ui/consts/issue-21562.rs
 ui/consts/issue-21721.rs
@@ -845,6 +859,8 @@ ui/cycle-trait/issue-12511.rs
 ui/debuginfo/issue-105386-debuginfo-ub.rs
 ui/deprecation/issue-66340-deprecated-attr-non-meta-grammar.rs
 ui/deprecation/issue-84637-deprecated-associated-function.rs
+ui/deref-patterns/issue-71676-1.rs
+ui/deref-patterns/issue-71676-2.rs
 ui/derived-errors/issue-30580.rs
 ui/derived-errors/issue-31997-1.rs
 ui/derived-errors/issue-31997.rs
@@ -952,7 +968,12 @@ ui/enum-discriminant/issue-70453-polymorphic-ctfe.rs
 ui/enum-discriminant/issue-70509-partial_eq.rs
 ui/enum-discriminant/issue-72554.rs
 ui/enum-discriminant/issue-90038.rs
+ui/enum/auxiliary/issue-19340-1.rs
 ui/enum/issue-1821.rs
+ui/enum/issue-19340-1.rs
+ui/enum/issue-19340-2.rs
+ui/enum/issue-23304-1.rs
+ui/enum/issue-23304-2.rs
 ui/enum/issue-42747.rs
 ui/enum/issue-67945-1.rs
 ui/enum/issue-67945-2.rs
@@ -965,6 +986,8 @@ ui/errors/issue-104621-extern-not-file.rs
 ui/errors/issue-89280-emitter-overflow-splice-lines.rs
 ui/errors/issue-99572-impl-trait-on-pointer.rs
 ui/expr/if/issue-4201.rs
+ui/expr/issue-22933-1.rs
+ui/expr/issue-22933-2.rs
 ui/extern/auxiliary/issue-80074-macro-2.rs
 ui/extern/auxiliary/issue-80074-macro.rs
 ui/extern/issue-10025.rs
@@ -1400,7 +1423,6 @@ ui/issues/auxiliary/issue-18711.rs
 ui/issues/auxiliary/issue-18913-1.rs
 ui/issues/auxiliary/issue-18913-2.rs
 ui/issues/auxiliary/issue-19293.rs
-ui/issues/auxiliary/issue-19340-1.rs
 ui/issues/auxiliary/issue-20389.rs
 ui/issues/auxiliary/issue-21202.rs
 ui/issues/auxiliary/issue-2170-lib.rs
@@ -1492,8 +1514,6 @@ ui/issues/issue-11592.rs
 ui/issues/issue-11677.rs
 ui/issues/issue-11680.rs
 ui/issues/issue-11681.rs
-ui/issues/issue-11692-1.rs
-ui/issues/issue-11692-2.rs
 ui/issues/issue-11709.rs
 ui/issues/issue-11740.rs
 ui/issues/issue-11771.rs
@@ -1504,8 +1524,6 @@ ui/issues/issue-11958.rs
 ui/issues/issue-12033.rs
 ui/issues/issue-12041.rs
 ui/issues/issue-12127.rs
-ui/issues/issue-12187-1.rs
-ui/issues/issue-12187-2.rs
 ui/issues/issue-12285.rs
 ui/issues/issue-12567.rs
 ui/issues/issue-12612.rs
@@ -1713,14 +1731,8 @@ ui/issues/issue-19097.rs
 ui/issues/issue-19098.rs
 ui/issues/issue-19100.rs
 ui/issues/issue-19127.rs
-ui/issues/issue-19129-1.rs
-ui/issues/issue-19129-2.rs
 ui/issues/issue-19135.rs
-ui/issues/issue-19244-1.rs
-ui/issues/issue-19244-2.rs
 ui/issues/issue-19293.rs
-ui/issues/issue-19340-1.rs
-ui/issues/issue-19340-2.rs
 ui/issues/issue-19367.rs
 ui/issues/issue-19380.rs
 ui/issues/issue-19398.rs
@@ -1761,8 +1773,6 @@ ui/issues/issue-20644.rs
 ui/issues/issue-20676.rs
 ui/issues/issue-20714.rs
 ui/issues/issue-2074.rs
-ui/issues/issue-20763-1.rs
-ui/issues/issue-20763-2.rs
 ui/issues/issue-20772.rs
 ui/issues/issue-20797.rs
 ui/issues/issue-20803.rs
@@ -1835,15 +1845,11 @@ ui/issues/issue-22789.rs
 ui/issues/issue-2281-part1.rs
 ui/issues/issue-22814.rs
 ui/issues/issue-2284.rs
-ui/issues/issue-22864-1.rs
-ui/issues/issue-22864-2.rs
 ui/issues/issue-22872.rs
 ui/issues/issue-22874.rs
 ui/issues/issue-2288.rs
 ui/issues/issue-22886.rs
 ui/issues/issue-22894.rs
-ui/issues/issue-22933-1.rs
-ui/issues/issue-22933-2.rs
 ui/issues/issue-22992-2.rs
 ui/issues/issue-22992.rs
 ui/issues/issue-23024.rs
@@ -1854,8 +1860,6 @@ ui/issues/issue-23073.rs
 ui/issues/issue-2311-2.rs
 ui/issues/issue-2311.rs
 ui/issues/issue-2312.rs
-ui/issues/issue-23122-1.rs
-ui/issues/issue-23122-2.rs
 ui/issues/issue-2316-c.rs
 ui/issues/issue-23173.rs
 ui/issues/issue-23189.rs
@@ -1863,8 +1867,6 @@ ui/issues/issue-23217.rs
 ui/issues/issue-23253.rs
 ui/issues/issue-23261.rs
 ui/issues/issue-23281.rs
-ui/issues/issue-23304-1.rs
-ui/issues/issue-23304-2.rs
 ui/issues/issue-23311.rs
 ui/issues/issue-23336.rs
 ui/issues/issue-23354-2.rs
@@ -2092,9 +2094,6 @@ ui/issues/issue-31910.rs
 ui/issues/issue-32004.rs
 ui/issues/issue-32008.rs
 ui/issues/issue-32086.rs
-ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.rs
-ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.rs
-ui/issues/issue-3214.rs
 ui/issues/issue-3220.rs
 ui/issues/issue-32292.rs
 ui/issues/issue-32324.rs
@@ -2243,8 +2242,6 @@ ui/issues/issue-4025.rs
 ui/issues/issue-40288-2.rs
 ui/issues/issue-40288.rs
 ui/issues/issue-40350.rs
-ui/issues/issue-40402-ref-hints/issue-40402-1.rs
-ui/issues/issue-40402-ref-hints/issue-40402-2.rs
 ui/issues/issue-40408.rs
 ui/issues/issue-40610.rs
 ui/issues/issue-40749.rs
@@ -2438,8 +2435,6 @@ ui/issues/issue-51947.rs
 ui/issues/issue-52049.rs
 ui/issues/issue-52126-assign-op-invariance.rs
 ui/issues/issue-52262.rs
-ui/issues/issue-5239-1.rs
-ui/issues/issue-5239-2.rs
 ui/issues/issue-52489.rs
 ui/issues/issue-52533.rs
 ui/issues/issue-52717.rs
@@ -2491,8 +2486,6 @@ ui/issues/issue-57162.rs
 ui/issues/issue-5718.rs
 ui/issues/issue-57198-pass.rs
 ui/issues/issue-57271.rs
-ui/issues/issue-57362-1.rs
-ui/issues/issue-57362-2.rs
 ui/issues/issue-57399-self-return-impl-trait.rs
 ui/issues/issue-5741.rs
 ui/issues/issue-5754.rs
@@ -2578,8 +2571,6 @@ ui/issues/issue-70724-add_type_neq_err_label-unwrap.rs
 ui/issues/issue-70746.rs
 ui/issues/issue-7092.rs
 ui/issues/issue-71406.rs
-ui/issues/issue-71676-suggest-deref/issue-71676-1.rs
-ui/issues/issue-71676-suggest-deref/issue-71676-2.rs
 ui/issues/issue-7178.rs
 ui/issues/issue-72002.rs
 ui/issues/issue-72076.rs
@@ -2600,8 +2591,6 @@ ui/issues/issue-7563.rs
 ui/issues/issue-75704.rs
 ui/issues/issue-7575.rs
 ui/issues/issue-76042.rs
-ui/issues/issue-7607-1.rs
-ui/issues/issue-7607-2.rs
 ui/issues/issue-76077-inaccesible-private-fields/issue-76077-1.rs
 ui/issues/issue-76077-inaccesible-private-fields/issue-76077.rs
 ui/issues/issue-76191.rs
@@ -2851,6 +2840,8 @@ ui/macros/issue-109237.rs
 ui/macros/issue-111749.rs
 ui/macros/issue-112342-1.rs
 ui/macros/issue-112342-2.rs
+ui/macros/issue-11692-1.rs
+ui/macros/issue-11692-2.rs
 ui/macros/issue-118048.rs
 ui/macros/issue-118786.rs
 ui/macros/issue-16098.rs
@@ -3162,6 +3153,8 @@ ui/nll/issue-57265-return-type-wf-check.rs
 ui/nll/issue-57280-1-flipped.rs
 ui/nll/issue-57280-1.rs
 ui/nll/issue-57280.rs
+ui/nll/issue-57362-1.rs
+ui/nll/issue-57362-2.rs
 ui/nll/issue-57642-higher-ranked-subtype.rs
 ui/nll/issue-57843.rs
 ui/nll/issue-57960.rs
@@ -3218,6 +3211,8 @@ ui/packed/issue-27060.rs
 ui/packed/issue-46152.rs
 ui/panics/issue-47429-short-backtraces.rs
 ui/parser/issue-116781.rs
+ui/parser/issue-12187-1.rs
+ui/parser/issue-12187-2.rs
 ui/parser/issues/auxiliary/issue-21146-inc.rs
 ui/parser/issues/auxiliary/issue-89971-outer-attr-following-inner-attr-ice.rs
 ui/parser/issues/auxiliary/issue-94340-inc.rs
@@ -3613,6 +3608,8 @@ ui/reachable/issue-11225-1.rs
 ui/reachable/issue-11225-2.rs
 ui/reachable/issue-11225-3.rs
 ui/reachable/issue-948.rs
+ui/recursion/issue-23122-1.rs
+ui/recursion/issue-23122-2.rs
 ui/recursion/issue-23302-1.rs
 ui/recursion/issue-23302-2.rs
 ui/recursion/issue-23302-3.rs
@@ -3692,6 +3689,7 @@ ui/resolve/issue-30535.rs
 ui/resolve/issue-3099-a.rs
 ui/resolve/issue-3099-b.rs
 ui/resolve/issue-31845.rs
+ui/resolve/issue-3214.rs
 ui/resolve/issue-33876.rs
 ui/resolve/issue-35675.rs
 ui/resolve/issue-3907-2.rs
@@ -4203,6 +4201,8 @@ ui/type/issue-102598.rs
 ui/type/issue-103271.rs
 ui/type/issue-58355.rs
 ui/type/issue-67690-type-alias-bound-diagnostic-crash.rs
+ui/type/issue-7607-1.rs
+ui/type/issue-7607-2.rs
 ui/type/issue-91268.rs
 ui/type/issue-94187-verbose-type-name.rs
 ui/type/type-check/issue-116967-cannot-coerce-returned-result.rs
diff --git a/src/tools/tidy/src/ui_tests.rs b/src/tools/tidy/src/ui_tests.rs
index 7136bc4d8f2..f9985a75703 100644
--- a/src/tools/tidy/src/ui_tests.rs
+++ b/src/tools/tidy/src/ui_tests.rs
@@ -17,7 +17,7 @@ use std::path::{Path, PathBuf};
 const ENTRY_LIMIT: usize = 900;
 // FIXME: The following limits should be reduced eventually.
 
-const ISSUES_ENTRY_LIMIT: usize = 1720;
+const ISSUES_ENTRY_LIMIT: usize = 1676;
 const ROOT_ENTRY_LIMIT: usize = 859;
 
 const EXPECTED_TEST_FILE_EXTENSIONS: &[&str] = &[
diff --git a/tests/ui/issues/issue-19129-1.rs b/tests/ui/associated-types/issue-19129-1.rs
similarity index 100%
rename from tests/ui/issues/issue-19129-1.rs
rename to tests/ui/associated-types/issue-19129-1.rs
diff --git a/tests/ui/issues/issue-19129-2.rs b/tests/ui/associated-types/issue-19129-2.rs
similarity index 100%
rename from tests/ui/issues/issue-19129-2.rs
rename to tests/ui/associated-types/issue-19129-2.rs
diff --git a/tests/ui/issues/issue-20763-1.rs b/tests/ui/associated-types/issue-20763-1.rs
similarity index 100%
rename from tests/ui/issues/issue-20763-1.rs
rename to tests/ui/associated-types/issue-20763-1.rs
diff --git a/tests/ui/issues/issue-20763-2.rs b/tests/ui/associated-types/issue-20763-2.rs
similarity index 100%
rename from tests/ui/issues/issue-20763-2.rs
rename to tests/ui/associated-types/issue-20763-2.rs
diff --git a/tests/ui/issues/issue-40402-ref-hints/issue-40402-1.rs b/tests/ui/binding/issue-40402-1.rs
similarity index 100%
rename from tests/ui/issues/issue-40402-ref-hints/issue-40402-1.rs
rename to tests/ui/binding/issue-40402-1.rs
diff --git a/tests/ui/issues/issue-40402-ref-hints/issue-40402-1.stderr b/tests/ui/binding/issue-40402-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-40402-ref-hints/issue-40402-1.stderr
rename to tests/ui/binding/issue-40402-1.stderr
diff --git a/tests/ui/issues/issue-40402-ref-hints/issue-40402-2.rs b/tests/ui/binding/issue-40402-2.rs
similarity index 100%
rename from tests/ui/issues/issue-40402-ref-hints/issue-40402-2.rs
rename to tests/ui/binding/issue-40402-2.rs
diff --git a/tests/ui/issues/issue-40402-ref-hints/issue-40402-2.stderr b/tests/ui/binding/issue-40402-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-40402-ref-hints/issue-40402-2.stderr
rename to tests/ui/binding/issue-40402-2.stderr
diff --git a/tests/ui/issues/issue-22864-1.rs b/tests/ui/closures/issue-22864-1.rs
similarity index 100%
rename from tests/ui/issues/issue-22864-1.rs
rename to tests/ui/closures/issue-22864-1.rs
diff --git a/tests/ui/issues/issue-22864-2.rs b/tests/ui/closures/issue-22864-2.rs
similarity index 100%
rename from tests/ui/issues/issue-22864-2.rs
rename to tests/ui/closures/issue-22864-2.rs
diff --git a/tests/ui/issues/issue-5239-1.rs b/tests/ui/closures/issue-5239-1.rs
similarity index 100%
rename from tests/ui/issues/issue-5239-1.rs
rename to tests/ui/closures/issue-5239-1.rs
diff --git a/tests/ui/issues/issue-5239-1.stderr b/tests/ui/closures/issue-5239-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-5239-1.stderr
rename to tests/ui/closures/issue-5239-1.stderr
diff --git a/tests/ui/issues/issue-5239-2.rs b/tests/ui/closures/issue-5239-2.rs
similarity index 100%
rename from tests/ui/issues/issue-5239-2.rs
rename to tests/ui/closures/issue-5239-2.rs
diff --git a/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.fixed b/tests/ui/coercion/issue-32122-1.fixed
similarity index 100%
rename from tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.fixed
rename to tests/ui/coercion/issue-32122-1.fixed
diff --git a/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.rs b/tests/ui/coercion/issue-32122-1.rs
similarity index 100%
rename from tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.rs
rename to tests/ui/coercion/issue-32122-1.rs
diff --git a/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.stderr b/tests/ui/coercion/issue-32122-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-1.stderr
rename to tests/ui/coercion/issue-32122-1.stderr
diff --git a/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.fixed b/tests/ui/coercion/issue-32122-2.fixed
similarity index 100%
rename from tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.fixed
rename to tests/ui/coercion/issue-32122-2.fixed
diff --git a/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.rs b/tests/ui/coercion/issue-32122-2.rs
similarity index 100%
rename from tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.rs
rename to tests/ui/coercion/issue-32122-2.rs
diff --git a/tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.stderr b/tests/ui/coercion/issue-32122-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-32122-deref-coercions-composition/issue-32122-2.stderr
rename to tests/ui/coercion/issue-32122-2.stderr
diff --git a/tests/ui/issues/issue-19244-1.rs b/tests/ui/consts/issue-19244-1.rs
similarity index 100%
rename from tests/ui/issues/issue-19244-1.rs
rename to tests/ui/consts/issue-19244-1.rs
diff --git a/tests/ui/issues/issue-19244-1.stderr b/tests/ui/consts/issue-19244-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-19244-1.stderr
rename to tests/ui/consts/issue-19244-1.stderr
diff --git a/tests/ui/issues/issue-19244-2.rs b/tests/ui/consts/issue-19244-2.rs
similarity index 100%
rename from tests/ui/issues/issue-19244-2.rs
rename to tests/ui/consts/issue-19244-2.rs
diff --git a/tests/ui/issues/issue-19244-2.stderr b/tests/ui/consts/issue-19244-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-19244-2.stderr
rename to tests/ui/consts/issue-19244-2.stderr
diff --git a/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.fixed b/tests/ui/deref-patterns/issue-71676-1.fixed
similarity index 100%
rename from tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.fixed
rename to tests/ui/deref-patterns/issue-71676-1.fixed
diff --git a/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.rs b/tests/ui/deref-patterns/issue-71676-1.rs
similarity index 100%
rename from tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.rs
rename to tests/ui/deref-patterns/issue-71676-1.rs
diff --git a/tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.stderr b/tests/ui/deref-patterns/issue-71676-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-71676-suggest-deref/issue-71676-1.stderr
rename to tests/ui/deref-patterns/issue-71676-1.stderr
diff --git a/tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.rs b/tests/ui/deref-patterns/issue-71676-2.rs
similarity index 100%
rename from tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.rs
rename to tests/ui/deref-patterns/issue-71676-2.rs
diff --git a/tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.stderr b/tests/ui/deref-patterns/issue-71676-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-71676-suggest-deref/issue-71676-2.stderr
rename to tests/ui/deref-patterns/issue-71676-2.stderr
diff --git a/tests/ui/issues/auxiliary/issue-19340-1.rs b/tests/ui/enum/auxiliary/issue-19340-1.rs
similarity index 100%
rename from tests/ui/issues/auxiliary/issue-19340-1.rs
rename to tests/ui/enum/auxiliary/issue-19340-1.rs
diff --git a/tests/ui/issues/issue-19340-1.rs b/tests/ui/enum/issue-19340-1.rs
similarity index 100%
rename from tests/ui/issues/issue-19340-1.rs
rename to tests/ui/enum/issue-19340-1.rs
diff --git a/tests/ui/issues/issue-19340-2.rs b/tests/ui/enum/issue-19340-2.rs
similarity index 100%
rename from tests/ui/issues/issue-19340-2.rs
rename to tests/ui/enum/issue-19340-2.rs
diff --git a/tests/ui/issues/issue-23304-1.rs b/tests/ui/enum/issue-23304-1.rs
similarity index 100%
rename from tests/ui/issues/issue-23304-1.rs
rename to tests/ui/enum/issue-23304-1.rs
diff --git a/tests/ui/issues/issue-23304-2.rs b/tests/ui/enum/issue-23304-2.rs
similarity index 100%
rename from tests/ui/issues/issue-23304-2.rs
rename to tests/ui/enum/issue-23304-2.rs
diff --git a/tests/ui/issues/issue-22933-1.rs b/tests/ui/expr/issue-22933-1.rs
similarity index 100%
rename from tests/ui/issues/issue-22933-1.rs
rename to tests/ui/expr/issue-22933-1.rs
diff --git a/tests/ui/issues/issue-22933-2.rs b/tests/ui/expr/issue-22933-2.rs
similarity index 100%
rename from tests/ui/issues/issue-22933-2.rs
rename to tests/ui/expr/issue-22933-2.rs
diff --git a/tests/ui/issues/issue-22933-2.stderr b/tests/ui/expr/issue-22933-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-22933-2.stderr
rename to tests/ui/expr/issue-22933-2.stderr
diff --git a/tests/ui/issues/issue-11692-1.rs b/tests/ui/macros/issue-11692-1.rs
similarity index 100%
rename from tests/ui/issues/issue-11692-1.rs
rename to tests/ui/macros/issue-11692-1.rs
diff --git a/tests/ui/issues/issue-11692-1.stderr b/tests/ui/macros/issue-11692-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-11692-1.stderr
rename to tests/ui/macros/issue-11692-1.stderr
diff --git a/tests/ui/issues/issue-11692-2.rs b/tests/ui/macros/issue-11692-2.rs
similarity index 100%
rename from tests/ui/issues/issue-11692-2.rs
rename to tests/ui/macros/issue-11692-2.rs
diff --git a/tests/ui/issues/issue-11692-2.stderr b/tests/ui/macros/issue-11692-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-11692-2.stderr
rename to tests/ui/macros/issue-11692-2.stderr
diff --git a/tests/ui/issues/issue-57362-1.rs b/tests/ui/nll/issue-57362-1.rs
similarity index 100%
rename from tests/ui/issues/issue-57362-1.rs
rename to tests/ui/nll/issue-57362-1.rs
diff --git a/tests/ui/issues/issue-57362-1.stderr b/tests/ui/nll/issue-57362-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-57362-1.stderr
rename to tests/ui/nll/issue-57362-1.stderr
diff --git a/tests/ui/issues/issue-57362-2.rs b/tests/ui/nll/issue-57362-2.rs
similarity index 100%
rename from tests/ui/issues/issue-57362-2.rs
rename to tests/ui/nll/issue-57362-2.rs
diff --git a/tests/ui/issues/issue-57362-2.stderr b/tests/ui/nll/issue-57362-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-57362-2.stderr
rename to tests/ui/nll/issue-57362-2.stderr
diff --git a/tests/ui/issues/issue-12187-1.rs b/tests/ui/parser/issue-12187-1.rs
similarity index 100%
rename from tests/ui/issues/issue-12187-1.rs
rename to tests/ui/parser/issue-12187-1.rs
diff --git a/tests/ui/issues/issue-12187-1.stderr b/tests/ui/parser/issue-12187-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-12187-1.stderr
rename to tests/ui/parser/issue-12187-1.stderr
diff --git a/tests/ui/issues/issue-12187-2.rs b/tests/ui/parser/issue-12187-2.rs
similarity index 100%
rename from tests/ui/issues/issue-12187-2.rs
rename to tests/ui/parser/issue-12187-2.rs
diff --git a/tests/ui/issues/issue-12187-2.stderr b/tests/ui/parser/issue-12187-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-12187-2.stderr
rename to tests/ui/parser/issue-12187-2.stderr
diff --git a/tests/ui/issues/issue-23122-1.rs b/tests/ui/recursion/issue-23122-1.rs
similarity index 100%
rename from tests/ui/issues/issue-23122-1.rs
rename to tests/ui/recursion/issue-23122-1.rs
diff --git a/tests/ui/issues/issue-23122-1.stderr b/tests/ui/recursion/issue-23122-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-23122-1.stderr
rename to tests/ui/recursion/issue-23122-1.stderr
diff --git a/tests/ui/issues/issue-23122-2.rs b/tests/ui/recursion/issue-23122-2.rs
similarity index 100%
rename from tests/ui/issues/issue-23122-2.rs
rename to tests/ui/recursion/issue-23122-2.rs
diff --git a/tests/ui/issues/issue-23122-2.stderr b/tests/ui/recursion/issue-23122-2.stderr
similarity index 100%
rename from tests/ui/issues/issue-23122-2.stderr
rename to tests/ui/recursion/issue-23122-2.stderr
diff --git a/tests/ui/issues/issue-3214.rs b/tests/ui/resolve/issue-3214.rs
similarity index 100%
rename from tests/ui/issues/issue-3214.rs
rename to tests/ui/resolve/issue-3214.rs
diff --git a/tests/ui/issues/issue-3214.stderr b/tests/ui/resolve/issue-3214.stderr
similarity index 100%
rename from tests/ui/issues/issue-3214.stderr
rename to tests/ui/resolve/issue-3214.stderr
diff --git a/tests/ui/issues/issue-7607-1.rs b/tests/ui/type/issue-7607-1.rs
similarity index 100%
rename from tests/ui/issues/issue-7607-1.rs
rename to tests/ui/type/issue-7607-1.rs
diff --git a/tests/ui/issues/issue-7607-1.stderr b/tests/ui/type/issue-7607-1.stderr
similarity index 100%
rename from tests/ui/issues/issue-7607-1.stderr
rename to tests/ui/type/issue-7607-1.stderr
diff --git a/tests/ui/issues/issue-7607-2.rs b/tests/ui/type/issue-7607-2.rs
similarity index 100%
rename from tests/ui/issues/issue-7607-2.rs
rename to tests/ui/type/issue-7607-2.rs