diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 24c6e0eae3674..8997161897f32 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -157,7 +157,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     /// [ 0. Pre-match ]
     ///        |
     /// [ 1. Evaluate Scrutinee (expression being matched on) ]
-    /// [ (fake read of scrutinee) ]
+    /// [ (PlaceMention of scrutinee) ]
     ///        |
     /// [ 2. Decision tree -- check discriminants ] <--------+
     ///        |                                             |
@@ -184,7 +184,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
     ///
     /// We generate MIR in the following steps:
     ///
-    /// 1. Evaluate the scrutinee and add the fake read of it ([Builder::lower_scrutinee]).
+    /// 1. Evaluate the scrutinee and add the PlaceMention of it ([Builder::lower_scrutinee]).
     /// 2. Create the decision tree ([Builder::lower_match_tree]).
     /// 3. Determine the fake borrows that are needed from the places that were
     ///    matched against and create the required temporaries for them
@@ -223,6 +223,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let fake_borrow_temps = self.lower_match_tree(
             block,
             scrutinee_span,
+            &scrutinee_place,
             match_start_span,
             match_has_guard,
             &mut candidates,
@@ -238,7 +239,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         )
     }
 
-    /// Evaluate the scrutinee and add the fake read of it.
+    /// Evaluate the scrutinee and add the PlaceMention for it.
     fn lower_scrutinee(
         &mut self,
         mut block: BasicBlock,
@@ -246,26 +247,9 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         scrutinee_span: Span,
     ) -> BlockAnd<PlaceBuilder<'tcx>> {
         let scrutinee_place_builder = unpack!(block = self.as_place_builder(block, scrutinee));
-        // Matching on a `scrutinee_place` with an uninhabited type doesn't
-        // generate any memory reads by itself, and so if the place "expression"
-        // contains unsafe operations like raw pointer dereferences or union
-        // field projections, we wouldn't know to require an `unsafe` block
-        // around a `match` equivalent to `std::intrinsics::unreachable()`.
-        // See issue #47412 for this hole being discovered in the wild.
-        //
-        // HACK(eddyb) Work around the above issue by adding a dummy inspection
-        // of `scrutinee_place`, specifically by applying `ReadForMatch`.
-        //
-        // NOTE: ReadForMatch also checks that the scrutinee is initialized.
-        // This is currently needed to not allow matching on an uninitialized,
-        // uninhabited value. If we get never patterns, those will check that
-        // the place is initialized, and so this read would only be used to
-        // check safety.
-        let cause_matched_place = FakeReadCause::ForMatchedPlace(None);
-        let source_info = self.source_info(scrutinee_span);
-
         if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) {
-            self.cfg.push_fake_read(block, source_info, cause_matched_place, scrutinee_place);
+            let source_info = self.source_info(scrutinee_span);
+            self.cfg.push_place_mention(block, source_info, scrutinee_place);
         }
 
         block.and(scrutinee_place_builder)
@@ -304,6 +288,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         &mut self,
         block: BasicBlock,
         scrutinee_span: Span,
+        scrutinee_place_builder: &PlaceBuilder<'tcx>,
         match_start_span: Span,
         match_has_guard: bool,
         candidates: &mut [&mut Candidate<'pat, 'tcx>],
@@ -331,6 +316,33 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             // otherwise block. Match checking will ensure this is actually
             // unreachable.
             let source_info = self.source_info(scrutinee_span);
+
+            // Matching on a `scrutinee_place` with an uninhabited type doesn't
+            // generate any memory reads by itself, and so if the place "expression"
+            // contains unsafe operations like raw pointer dereferences or union
+            // field projections, we wouldn't know to require an `unsafe` block
+            // around a `match` equivalent to `std::intrinsics::unreachable()`.
+            // See issue #47412 for this hole being discovered in the wild.
+            //
+            // HACK(eddyb) Work around the above issue by adding a dummy inspection
+            // of `scrutinee_place`, specifically by applying `ReadForMatch`.
+            //
+            // NOTE: ReadForMatch also checks that the scrutinee is initialized.
+            // This is currently needed to not allow matching on an uninitialized,
+            // uninhabited value. If we get never patterns, those will check that
+            // the place is initialized, and so this read would only be used to
+            // check safety.
+            let cause_matched_place = FakeReadCause::ForMatchedPlace(None);
+
+            if let Some(scrutinee_place) = scrutinee_place_builder.try_to_place(self) {
+                self.cfg.push_fake_read(
+                    otherwise_block,
+                    source_info,
+                    cause_matched_place,
+                    scrutinee_place,
+                );
+            }
+
             self.cfg.terminate(otherwise_block, source_info, TerminatorKind::Unreachable);
         }
 
@@ -599,13 +611,8 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             }
 
             _ => {
-                let place_builder = unpack!(block = self.as_place_builder(block, initializer));
-
-                if let Some(place) = place_builder.try_to_place(self) {
-                    let source_info = self.source_info(initializer.span);
-                    self.cfg.push_place_mention(block, source_info, place);
-                }
-
+                let place_builder =
+                    unpack!(block = self.lower_scrutinee(block, initializer, initializer.span));
                 self.place_into_pattern(block, &irrefutable_pat, place_builder, true)
             }
         }
@@ -622,6 +629,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let fake_borrow_temps = self.lower_match_tree(
             block,
             irrefutable_pat.span,
+            &initializer,
             irrefutable_pat.span,
             false,
             &mut [&mut candidate],
@@ -1837,6 +1845,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
         let fake_borrow_temps = self.lower_match_tree(
             block,
             pat.span,
+            &expr_place_builder,
             pat.span,
             false,
             &mut [&mut guard_candidate, &mut otherwise_candidate],
@@ -2338,6 +2347,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             let fake_borrow_temps = this.lower_match_tree(
                 block,
                 initializer_span,
+                &scrutinee,
                 pattern.span,
                 false,
                 &mut [&mut candidate, &mut wildcard],
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.rs b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.rs
new file mode 100644
index 0000000000000..723c3f1e15897
--- /dev/null
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.rs
@@ -0,0 +1,17 @@
+// Make sure we find these even with many checks disabled.
+//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation
+
+#![allow(unreachable_code)]
+#![feature(never_type)]
+
+fn main() {
+    let p = {
+        let b = Box::new(42);
+        &*b as *const i32 as *const !
+    };
+    unsafe {
+        match *p {} //~ ERROR: entering unreachable code
+    }
+    panic!("this should never print");
+}
+
diff --git a/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.stderr b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.stderr
new file mode 100644
index 0000000000000..2ca6fd028b0b2
--- /dev/null
+++ b/src/tools/miri/tests/fail/dangling_pointers/dangling_pointer_deref_match_never.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: entering unreachable code
+  --> $DIR/dangling_pointer_deref_match_never.rs:LL:CC
+   |
+LL |         match *p {}
+   |               ^^ entering unreachable code
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/dangling_pointer_deref_match_never.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/fail/never_match_never.rs b/src/tools/miri/tests/fail/never_match_never.rs
new file mode 100644
index 0000000000000..5f2f471bf6098
--- /dev/null
+++ b/src/tools/miri/tests/fail/never_match_never.rs
@@ -0,0 +1,10 @@
+// This should fail even without validation
+//@compile-flags: -Zmiri-disable-validation
+
+#![feature(never_type)]
+#![allow(unreachable_code)]
+
+fn main() {
+    let ptr: *const (i32, !) = &0i32 as *const i32 as *const _;
+    unsafe { match (*ptr).1 {} } //~ ERROR: entering unreachable code
+}
diff --git a/src/tools/miri/tests/fail/never_match_never.stderr b/src/tools/miri/tests/fail/never_match_never.stderr
new file mode 100644
index 0000000000000..33dab81d5b081
--- /dev/null
+++ b/src/tools/miri/tests/fail/never_match_never.stderr
@@ -0,0 +1,15 @@
+error: Undefined Behavior: entering unreachable code
+  --> $DIR/never_match_never.rs:LL:CC
+   |
+LL |     unsafe { match (*ptr).1 {} }
+   |                    ^^^^^^^^ entering unreachable code
+   |
+   = help: this indicates a bug in the program: it performed an invalid operation, and caused Undefined Behavior
+   = help: see https://doc.rust-lang.org/nightly/reference/behavior-considered-undefined.html for further information
+   = note: BACKTRACE:
+   = note: inside `main` at $DIR/never_match_never.rs:LL:CC
+
+note: some details are omitted, run with `MIRIFLAGS=-Zmiri-backtrace=full` for a verbose backtrace
+
+error: aborting due to previous error
+
diff --git a/src/tools/miri/tests/pass/dangling_pointer_deref_match_underscore.rs b/src/tools/miri/tests/pass/dangling_pointer_deref_match_underscore.rs
new file mode 100644
index 0000000000000..c3cff1f4280f4
--- /dev/null
+++ b/src/tools/miri/tests/pass/dangling_pointer_deref_match_underscore.rs
@@ -0,0 +1,14 @@
+// A `_` binding in a match is a nop, so we do not detect that the pointer is dangling.
+//@compile-flags: -Zmiri-disable-alignment-check -Zmiri-disable-stacked-borrows -Zmiri-disable-validation
+
+fn main() {
+    let p = {
+        let b = Box::new(42);
+        &*b as *const i32
+    };
+    unsafe {
+        match *p {
+            _ => {}
+        }
+    }
+}
diff --git a/src/tools/miri/tests/pass/union-uninhabited-match-underscore.rs b/src/tools/miri/tests/pass/union-uninhabited-match-underscore.rs
new file mode 100644
index 0000000000000..33db9c2d347b2
--- /dev/null
+++ b/src/tools/miri/tests/pass/union-uninhabited-match-underscore.rs
@@ -0,0 +1,17 @@
+fn main() {
+    #[derive(Copy, Clone)]
+    enum Void {}
+    union Uninit<T: Copy> {
+        value: T,
+        uninit: (),
+    }
+    unsafe {
+        let x: Uninit<Void> = Uninit { uninit: () };
+        match x.value {
+            // rustc warns about un unreachable pattern,
+            // but is wrong in unsafe code.
+            #[allow(unreachable_patterns)]
+            _ => println!("hi from the void!"),
+        }
+    }
+}
diff --git a/src/tools/miri/tests/pass/union-uninhabited-match-underscore.stdout b/src/tools/miri/tests/pass/union-uninhabited-match-underscore.stdout
new file mode 100644
index 0000000000000..ff731696f01a5
--- /dev/null
+++ b/src/tools/miri/tests/pass/union-uninhabited-match-underscore.stdout
@@ -0,0 +1 @@
+hi from the void!
diff --git a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
index f64b540c3a5ef..396e4a378f6f6 100644
--- a/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
+++ b/tests/mir-opt/building/async_await.b-{closure#0}.coroutine_resume.0.mir
@@ -127,6 +127,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
 
     bb3: {
         StorageDead(_5);
+        PlaceMention(_4);
         nop;
         (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#3).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _4;
         goto -> bb4;
@@ -162,6 +163,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
     bb7: {
         StorageDead(_13);
         StorageDead(_10);
+        PlaceMention(_9);
         _16 = discriminant(_9);
         switchInt(move _16) -> [0: bb10, 1: bb8, otherwise: bb9];
     }
@@ -223,6 +225,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
 
     bb15: {
         StorageDead(_22);
+        PlaceMention(_21);
         nop;
         (((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2})) as variant#4).0: {async fn body@$DIR/async_await.rs:12:14: 12:16}) = move _21;
         goto -> bb16;
@@ -258,6 +261,7 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
     bb19: {
         StorageDead(_29);
         StorageDead(_26);
+        PlaceMention(_25);
         _32 = discriminant(_25);
         switchInt(move _32) -> [0: bb21, 1: bb20, otherwise: bb9];
     }
diff --git a/tests/mir-opt/building/issue_101867.main.built.after.mir b/tests/mir-opt/building/issue_101867.main.built.after.mir
index fb60f0f0c2b27..57f8cca9abc75 100644
--- a/tests/mir-opt/building/issue_101867.main.built.after.mir
+++ b/tests/mir-opt/building/issue_101867.main.built.after.mir
@@ -25,7 +25,7 @@ fn main() -> () {
         FakeRead(ForLet(None), _1);
         AscribeUserType(_1, o, UserTypeProjection { base: UserType(1), projs: [] });
         StorageLive(_5);
-        FakeRead(ForMatchedPlace(None), _1);
+        PlaceMention(_1);
         _6 = discriminant(_1);
         switchInt(move _6) -> [1: bb4, otherwise: bb3];
     }
diff --git a/tests/mir-opt/building/issue_49232.main.built.after.mir b/tests/mir-opt/building/issue_49232.main.built.after.mir
index f809132bc63f7..ac50b38891079 100644
--- a/tests/mir-opt/building/issue_49232.main.built.after.mir
+++ b/tests/mir-opt/building/issue_49232.main.built.after.mir
@@ -24,7 +24,7 @@ fn main() -> () {
         StorageLive(_2);
         StorageLive(_3);
         _3 = const true;
-        FakeRead(ForMatchedPlace(None), _3);
+        PlaceMention(_3);
         switchInt(_3) -> [0: bb3, otherwise: bb4];
     }
 
diff --git a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
index 096aaec4a3888..7407e7a8b2a17 100644
--- a/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
+++ b/tests/mir-opt/building/logical_or_in_conditional.test_complex.built.after.mir
@@ -23,7 +23,7 @@ fn test_complex() -> () {
     }
 
     bb1: {
-        FakeRead(ForMatchedPlace(None), _2);
+        PlaceMention(_2);
         _3 = discriminant(_2);
         switchInt(move _3) -> [0: bb2, otherwise: bb3];
     }
@@ -151,7 +151,7 @@ fn test_complex() -> () {
     }
 
     bb25: {
-        FakeRead(ForMatchedPlace(None), _12);
+        PlaceMention(_12);
         _13 = discriminant(_12);
         switchInt(move _13) -> [1: bb27, otherwise: bb26];
     }
diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
index bd4cd4eb6789a..1946c70e47642 100644
--- a/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
+++ b/tests/mir-opt/building/match_false_edges.full_tested_match.built.after.mir
@@ -26,7 +26,7 @@ fn full_tested_match() -> () {
         StorageLive(_1);
         StorageLive(_2);
         _2 = Option::<i32>::Some(const 42_i32);
-        FakeRead(ForMatchedPlace(None), _2);
+        PlaceMention(_2);
         _3 = discriminant(_2);
         switchInt(move _3) -> [0: bb1, 1: bb2, otherwise: bb4];
     }
@@ -45,6 +45,7 @@ fn full_tested_match() -> () {
     }
 
     bb4: {
+        FakeRead(ForMatchedPlace(None), _2);
         unreachable;
     }
 
diff --git a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
index 595e3ab9224d9..b6175b0515683 100644
--- a/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
+++ b/tests/mir-opt/building/match_false_edges.full_tested_match2.built.after.mir
@@ -26,7 +26,7 @@ fn full_tested_match2() -> () {
         StorageLive(_1);
         StorageLive(_2);
         _2 = Option::<i32>::Some(const 42_i32);
-        FakeRead(ForMatchedPlace(None), _2);
+        PlaceMention(_2);
         _3 = discriminant(_2);
         switchInt(move _3) -> [0: bb1, 1: bb2, otherwise: bb4];
     }
@@ -51,6 +51,7 @@ fn full_tested_match2() -> () {
     }
 
     bb4: {
+        FakeRead(ForMatchedPlace(None), _2);
         unreachable;
     }
 
diff --git a/tests/mir-opt/building/match_false_edges.main.built.after.mir b/tests/mir-opt/building/match_false_edges.main.built.after.mir
index 91fe2f90e35b2..0b57d1b97e15d 100644
--- a/tests/mir-opt/building/match_false_edges.main.built.after.mir
+++ b/tests/mir-opt/building/match_false_edges.main.built.after.mir
@@ -37,7 +37,7 @@ fn main() -> () {
         StorageLive(_1);
         StorageLive(_2);
         _2 = Option::<i32>::Some(const 1_i32);
-        FakeRead(ForMatchedPlace(None), _2);
+        PlaceMention(_2);
         _4 = discriminant(_2);
         switchInt(move _4) -> [1: bb2, otherwise: bb1];
     }
diff --git a/tests/mir-opt/building/simple_match.match_bool.built.after.mir b/tests/mir-opt/building/simple_match.match_bool.built.after.mir
index c89ea2b6c85bf..06de4c5105125 100644
--- a/tests/mir-opt/building/simple_match.match_bool.built.after.mir
+++ b/tests/mir-opt/building/simple_match.match_bool.built.after.mir
@@ -5,7 +5,7 @@ fn match_bool(_1: bool) -> usize {
     let mut _0: usize;
 
     bb0: {
-        FakeRead(ForMatchedPlace(None), _1);
+        PlaceMention(_1);
         switchInt(_1) -> [0: bb2, otherwise: bb1];
     }
 
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff
index 100982382ddbf..16519749b8207 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.32bit.diff
@@ -4,6 +4,7 @@
   fn unreachable_box() -> ! {
       let mut _0: !;
       let _1: std::boxed::Box<Never>;
+      let mut _2: *const Never;
       scope 1 {
           debug x => _1;
       }
@@ -13,7 +14,9 @@
       bb0: {
           StorageLive(_1);
 -         _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
+-         _2 = (((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>).0: *const Never);
 +         _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
++         _2 = const {0x1 as *const Never};
           unreachable;
       }
   }
diff --git a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff
index 100982382ddbf..16519749b8207 100644
--- a/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff
+++ b/tests/mir-opt/const_prop/transmute.unreachable_box.ConstProp.64bit.diff
@@ -4,6 +4,7 @@
   fn unreachable_box() -> ! {
       let mut _0: !;
       let _1: std::boxed::Box<Never>;
+      let mut _2: *const Never;
       scope 1 {
           debug x => _1;
       }
@@ -13,7 +14,9 @@
       bb0: {
           StorageLive(_1);
 -         _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
+-         _2 = (((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>).0: *const Never);
 +         _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
++         _2 = const {0x1 as *const Never};
           unreachable;
       }
   }
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
index d0c298ba23311..5d17c47ae6664 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.32bit.diff
@@ -4,6 +4,7 @@
   fn unreachable_box() -> ! {
       let mut _0: !;
       let _1: std::boxed::Box<Never>;
+      let mut _2: *const Never;
       scope 1 {
           debug x => _1;
       }
@@ -14,6 +15,7 @@
           StorageLive(_1);
 -         _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
 +         _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
+          _2 = (((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>).0: *const Never);
           unreachable;
       }
   }
diff --git a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
index d0c298ba23311..5d17c47ae6664 100644
--- a/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
+++ b/tests/mir-opt/dataflow-const-prop/transmute.unreachable_box.DataflowConstProp.64bit.diff
@@ -4,6 +4,7 @@
   fn unreachable_box() -> ! {
       let mut _0: !;
       let _1: std::boxed::Box<Never>;
+      let mut _2: *const Never;
       scope 1 {
           debug x => _1;
       }
@@ -14,6 +15,7 @@
           StorageLive(_1);
 -         _1 = const 1_usize as std::boxed::Box<Never> (Transmute);
 +         _1 = const Box::<Never>(Unique::<Never> {{ pointer: NonNull::<Never> {{ pointer: {0x1 as *const Never} }}, _marker: PhantomData::<Never> }}, std::alloc::Global);
+          _2 = (((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>).0: *const Never);
           unreachable;
       }
   }
diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff
index 1f3b3ad649d6c..0fad716a2cb63 100644
--- a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff
+++ b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-abort.diff
@@ -35,6 +35,7 @@
   
       bb1: {
           StorageDead(_2);
+          PlaceMention(_1);
           StorageLive(_4);
           _4 = move _1;
           goto -> bb2;
@@ -52,6 +53,7 @@
   
       bb3: {
           StorageDead(_8);
+          PlaceMention(_7);
           _10 = discriminant(_7);
           switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5];
       }
diff --git a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff
index da4cc188cfa6f..ae5656f02a5a8 100644
--- a/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff
+++ b/tests/mir-opt/derefer_complex_case.main.Derefer.panic-unwind.diff
@@ -35,6 +35,7 @@
   
       bb1: {
           StorageDead(_2);
+          PlaceMention(_1);
           StorageLive(_4);
           _4 = move _1;
           goto -> bb2;
@@ -52,6 +53,7 @@
   
       bb3: {
           StorageDead(_8);
+          PlaceMention(_7);
           _10 = discriminant(_7);
           switchInt(move _10) -> [0: bb6, 1: bb4, otherwise: bb5];
       }
diff --git a/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-abort.diff b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-abort.diff
index 895dcf5798ebb..f4c034517f7e7 100644
--- a/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-abort.diff
+++ b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-abort.diff
@@ -12,6 +12,9 @@
 +     let mut _10: &&&bool;
 +     let mut _11: &&bool;
 +     let mut _12: &bool;
++     let mut _13: &&&bool;
++     let mut _14: &&bool;
++     let mut _15: &bool;
       scope 1 {
           debug b => _1;
           let _2: bool;
@@ -48,11 +51,16 @@
           _6 = &_7;
           _5 = &_6;
           _4 = &_5;
+-         PlaceMention((*(*(*(*_4)))));
 -         switchInt((*(*(*(*_4))))) -> [0: bb3, otherwise: bb4];
 +         _10 = deref_copy (*_4);
 +         _11 = deref_copy (*_10);
 +         _12 = deref_copy (*_11);
-+         switchInt((*_12)) -> [0: bb3, otherwise: bb4];
++         PlaceMention((*_12));
++         _13 = deref_copy (*_4);
++         _14 = deref_copy (*_13);
++         _15 = deref_copy (*_14);
++         switchInt((*_15)) -> [0: bb3, otherwise: bb4];
       }
   
       bb3: {
diff --git a/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff
index 19b26c901cbfc..e3c0c6b7dd271 100644
--- a/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff
+++ b/tests/mir-opt/derefer_terminator_test.main.Derefer.panic-unwind.diff
@@ -12,6 +12,9 @@
 +     let mut _10: &&&bool;
 +     let mut _11: &&bool;
 +     let mut _12: &bool;
++     let mut _13: &&&bool;
++     let mut _14: &&bool;
++     let mut _15: &bool;
       scope 1 {
           debug b => _1;
           let _2: bool;
@@ -48,11 +51,16 @@
           _6 = &_7;
           _5 = &_6;
           _4 = &_5;
+-         PlaceMention((*(*(*(*_4)))));
 -         switchInt((*(*(*(*_4))))) -> [0: bb3, otherwise: bb4];
 +         _10 = deref_copy (*_4);
 +         _11 = deref_copy (*_10);
 +         _12 = deref_copy (*_11);
-+         switchInt((*_12)) -> [0: bb3, otherwise: bb4];
++         PlaceMention((*_12));
++         _13 = deref_copy (*_4);
++         _14 = deref_copy (*_13);
++         _15 = deref_copy (*_14);
++         switchInt((*_15)) -> [0: bb3, otherwise: bb4];
       }
   
       bb3: {
diff --git a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
index fba616d0474f1..b04e09e88b8dd 100644
--- a/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/exponential_or.match_tuple.SimplifyCfg-initial.after.mir
@@ -18,7 +18,7 @@ fn match_tuple(_1: (u32, bool, Option<i32>, u32)) -> u32 {
     }
 
     bb0: {
-        FakeRead(ForMatchedPlace(None), _1);
+        PlaceMention(_1);
         switchInt((_1.0: u32)) -> [1: bb2, 4: bb2, otherwise: bb1];
     }
 
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff
index ae18ddc83664e..55d2629a5519c 100644
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-abort.diff
@@ -60,6 +60,7 @@
   
       bb5: {
           StorageDead(_3);
+          PlaceMention(_1);
           _5 = discriminant(_1);
           switchInt(move _5) -> [0: bb6, otherwise: bb7];
       }
diff --git a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
index d08113c0ba54c..c731b5646f681 100644
--- a/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
+++ b/tests/mir-opt/issue_41888.main.ElaborateDrops.panic-unwind.diff
@@ -60,6 +60,7 @@
   
       bb5: {
           StorageDead(_3);
+          PlaceMention(_1);
           _5 = discriminant(_1);
           switchInt(move _5) -> [0: bb6, otherwise: bb7];
       }
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
index 7346296785033..fadfdfc87be89 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-abort.mir
@@ -45,6 +45,7 @@ fn test() -> Option<Box<u32>> {
 
     bb2: {
         StorageDead(_7);
+        PlaceMention(_6);
         _8 = discriminant(_6);
         switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb4];
     }
diff --git a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
index 8264e2cabbc55..8f94165a108ef 100644
--- a/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
+++ b/tests/mir-opt/issue_62289.test.ElaborateDrops.before.panic-unwind.mir
@@ -45,6 +45,7 @@ fn test() -> Option<Box<u32>> {
 
     bb2: {
         StorageDead(_7);
+        PlaceMention(_6);
         _8 = discriminant(_6);
         switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb4];
     }
diff --git a/tests/mir-opt/issue_72181_1.f.built.after.mir b/tests/mir-opt/issue_72181_1.f.built.after.mir
index 16f34e4a44985..89da9a8011361 100644
--- a/tests/mir-opt/issue_72181_1.f.built.after.mir
+++ b/tests/mir-opt/issue_72181_1.f.built.after.mir
@@ -5,6 +5,7 @@ fn f(_1: Void) -> ! {
     let mut _0: !;
 
     bb0: {
+        PlaceMention(_1);
         FakeRead(ForMatchedPlace(None), _1);
         unreachable;
     }
diff --git a/tests/mir-opt/issue_99325.main.built.after.32bit.mir b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
index 188b53d28d7a4..ffb1aedd2ea90 100644
--- a/tests/mir-opt/issue_99325.main.built.after.32bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.32bit.mir
@@ -81,7 +81,7 @@ fn main() -> () {
         _2 = (move _3, move _5);
         StorageDead(_5);
         StorageDead(_3);
-        FakeRead(ForMatchedPlace(None), _2);
+        PlaceMention(_2);
         StorageLive(_8);
         _8 = (_2.0: &&[u8]);
         StorageLive(_9);
@@ -180,7 +180,7 @@ fn main() -> () {
         _23 = (move _24, move _26);
         StorageDead(_26);
         StorageDead(_24);
-        FakeRead(ForMatchedPlace(None), _23);
+        PlaceMention(_23);
         StorageLive(_28);
         _28 = (_23.0: &&[u8]);
         StorageLive(_29);
diff --git a/tests/mir-opt/issue_99325.main.built.after.64bit.mir b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
index 188b53d28d7a4..ffb1aedd2ea90 100644
--- a/tests/mir-opt/issue_99325.main.built.after.64bit.mir
+++ b/tests/mir-opt/issue_99325.main.built.after.64bit.mir
@@ -81,7 +81,7 @@ fn main() -> () {
         _2 = (move _3, move _5);
         StorageDead(_5);
         StorageDead(_3);
-        FakeRead(ForMatchedPlace(None), _2);
+        PlaceMention(_2);
         StorageLive(_8);
         _8 = (_2.0: &&[u8]);
         StorageLive(_9);
@@ -180,7 +180,7 @@ fn main() -> () {
         _23 = (move _24, move _26);
         StorageDead(_26);
         StorageDead(_24);
-        FakeRead(ForMatchedPlace(None), _23);
+        PlaceMention(_23);
         StorageLive(_28);
         _28 = (_23.0: &&[u8]);
         StorageLive(_29);
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff
index 49cc8b1afe3e4..c4a3358ffa3ab 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -4,6 +4,7 @@
   fn transmute_to_box_uninhabited() -> ! {
       let mut _0: !;
       let _1: std::boxed::Box<Never>;
+      let mut _2: *const Never;
       scope 1 {
           debug x => _1;
       }
@@ -16,6 +17,8 @@
       }
   
       bb1: {
+          _2 = (((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>).0: *const Never);
+          PlaceMention((*_2));
           unreachable;
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff
index 49cc8b1afe3e4..c4a3358ffa3ab 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_box_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -4,6 +4,7 @@
   fn transmute_to_box_uninhabited() -> ! {
       let mut _0: !;
       let _1: std::boxed::Box<Never>;
+      let mut _2: *const Never;
       scope 1 {
           debug x => _1;
       }
@@ -16,6 +17,8 @@
       }
   
       bb1: {
+          _2 = (((_1.0: std::ptr::Unique<Never>).0: std::ptr::NonNull<Never>).0: *const Never);
+          PlaceMention((*_2));
           unreachable;
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff
index 94c7ebe1520cb..c2c4ec0003c26 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -16,6 +16,7 @@
       }
   
       bb1: {
+          PlaceMention((*_1));
           unreachable;
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff
index 94c7ebe1520cb..c2c4ec0003c26 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_mut_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -16,6 +16,7 @@
       }
   
       bb1: {
+          PlaceMention((*_1));
           unreachable;
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff
index 6576616e0ca27..1b516a1f53b39 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-abort.diff
@@ -16,6 +16,7 @@
       }
   
       bb1: {
+          PlaceMention((*_1));
           unreachable;
       }
   }
diff --git a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff
index 6576616e0ca27..1b516a1f53b39 100644
--- a/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff
+++ b/tests/mir-opt/lower_intrinsics.transmute_to_ref_uninhabited.LowerIntrinsics.panic-unwind.diff
@@ -16,6 +16,7 @@
       }
   
       bb1: {
+          PlaceMention((*_1));
           unreachable;
       }
   }
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 3e817ff433b8a..2989582d03827 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-abort.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -31,7 +31,7 @@
       }
   
       bb0: {
--         FakeRead(ForMatchedPlace(None), _2);
+          PlaceMention(_2);
 -         switchInt((_2.0: bool)) -> [0: bb1, otherwise: bb2];
 +         switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1];
       }
diff --git a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
index 3e817ff433b8a..2989582d03827 100644
--- a/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
+++ b/tests/mir-opt/match_arm_scopes.complicated_match.panic-unwind.SimplifyCfg-initial.after-ElaborateDrops.after.diff
@@ -31,7 +31,7 @@
       }
   
       bb0: {
--         FakeRead(ForMatchedPlace(None), _2);
+          PlaceMention(_2);
 -         switchInt((_2.0: bool)) -> [0: bb1, otherwise: bb2];
 +         switchInt((_2.0: bool)) -> [0: bb5, otherwise: bb1];
       }
diff --git a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
index 7f8eb82c772fe..90ec3ab49ad00 100644
--- a/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
+++ b/tests/mir-opt/match_test.main.SimplifyCfg-initial.after.mir
@@ -26,7 +26,7 @@ fn main() -> () {
         _2 = const true;
         FakeRead(ForLet(None), _2);
         StorageLive(_3);
-        FakeRead(ForMatchedPlace(None), _1);
+        PlaceMention(_1);
         _6 = Le(const 0_i32, _1);
         switchInt(move _6) -> [0: bb4, otherwise: bb1];
     }
diff --git a/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-abort.diff b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-abort.diff
index 33322c41b0185..61329bb75d13e 100644
--- a/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-abort.diff
+++ b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-abort.diff
@@ -13,8 +13,7 @@
       let mut _8: bool;
   
       bb0: {
--         FakeRead(ForMatchedPlace(None), _1);
-+         nop;
+          PlaceMention(_1);
           _3 = discriminant(_1);
           switchInt(move _3) -> [1: bb2, otherwise: bb1];
       }
diff --git a/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-unwind.diff b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-unwind.diff
index 33322c41b0185..61329bb75d13e 100644
--- a/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-unwind.diff
+++ b/tests/mir-opt/remove_fake_borrows.match_guard.CleanupPostBorrowck.panic-unwind.diff
@@ -13,8 +13,7 @@
       let mut _8: bool;
   
       bb0: {
--         FakeRead(ForMatchedPlace(None), _1);
-+         nop;
+          PlaceMention(_1);
           _3 = discriminant(_1);
           switchInt(move _3) -> [1: bb2, otherwise: bb1];
       }
diff --git a/tests/ui/binding/issue-53114-borrow-checks.rs b/tests/ui/binding/issue-53114-borrow-checks.rs
index 7646472f45fac..6ab1f4f47dfb3 100644
--- a/tests/ui/binding/issue-53114-borrow-checks.rs
+++ b/tests/ui/binding/issue-53114-borrow-checks.rs
@@ -1,8 +1,9 @@
+// check-pass
 // Issue #53114: NLL's borrow check had some deviations from the old borrow
 // checker, and both had some deviations from our ideal state. This test
 // captures the behavior of how `_` bindings are handled with respect to how we
 // flag expressions that are meant to request unsafe blocks.
-#![allow(irrefutable_let_patterns)]
+#![allow(irrefutable_let_patterns, dropping_references)]
 struct M;
 
 fn let_wild_gets_moved_expr() {
@@ -19,29 +20,23 @@ fn let_wild_gets_moved_expr() {
 fn match_moved_expr_to_wild() {
     let m = M;
     drop(m);
-    match m { _ => { } } // #53114: should eventually be accepted too
-    //~^ ERROR [E0382]
+    match m { _ => { } } // #53114: accepted too
 
     let mm = (M, M); // variation on above with `_` in substructure
     match mm { (_x, _) => { } }
     match mm { (_, _y) => { } }
-    //~^ ERROR [E0382]
     match mm { (_, _) => { } }
-    //~^ ERROR [E0382]
 }
 
 fn if_let_moved_expr_to_wild() {
     let m = M;
     drop(m);
-    if let _ = m { } // #53114: should eventually be accepted too
-    //~^ ERROR [E0382]
+    if let _ = m { } // #53114: accepted too
 
     let mm = (M, M); // variation on above with `_` in substructure
     if let (_x, _) = mm { }
     if let (_, _y) = mm { }
-    //~^ ERROR [E0382]
     if let (_, _) = mm { }
-    //~^ ERROR [E0382]
 }
 
 fn let_wild_gets_borrowed_expr() {
diff --git a/tests/ui/binding/issue-53114-borrow-checks.stderr b/tests/ui/binding/issue-53114-borrow-checks.stderr
deleted file mode 100644
index 0ec2ae8839e79..0000000000000
--- a/tests/ui/binding/issue-53114-borrow-checks.stderr
+++ /dev/null
@@ -1,81 +0,0 @@
-error[E0382]: use of moved value: `m`
-  --> $DIR/issue-53114-borrow-checks.rs:22:11
-   |
-LL |     let m = M;
-   |         - move occurs because `m` has type `M`, which does not implement the `Copy` trait
-LL |     drop(m);
-   |          - value moved here
-LL |     match m { _ => { } } // #53114: should eventually be accepted too
-   |           ^ value used here after move
-
-error[E0382]: use of partially moved value: `mm`
-  --> $DIR/issue-53114-borrow-checks.rs:27:11
-   |
-LL |     match mm { (_x, _) => { } }
-   |                 -- value partially moved here
-LL |     match mm { (_, _y) => { } }
-   |           ^^ value used here after partial move
-   |
-   = note: partial move occurs because `mm.0` has type `M`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |     match mm { (ref _x, _) => { } }
-   |                 +++
-
-error[E0382]: use of partially moved value: `mm`
-  --> $DIR/issue-53114-borrow-checks.rs:29:11
-   |
-LL |     match mm { (_, _y) => { } }
-   |                    -- value partially moved here
-LL |
-LL |     match mm { (_, _) => { } }
-   |           ^^ value used here after partial move
-   |
-   = note: partial move occurs because `mm.1` has type `M`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |     match mm { (_, ref _y) => { } }
-   |                    +++
-
-error[E0382]: use of moved value: `m`
-  --> $DIR/issue-53114-borrow-checks.rs:36:16
-   |
-LL |     let m = M;
-   |         - move occurs because `m` has type `M`, which does not implement the `Copy` trait
-LL |     drop(m);
-   |          - value moved here
-LL |     if let _ = m { } // #53114: should eventually be accepted too
-   |                ^ value used here after move
-
-error[E0382]: use of partially moved value: `mm`
-  --> $DIR/issue-53114-borrow-checks.rs:41:22
-   |
-LL |     if let (_x, _) = mm { }
-   |             -- value partially moved here
-LL |     if let (_, _y) = mm { }
-   |                      ^^ value used here after partial move
-   |
-   = note: partial move occurs because `mm.0` has type `M`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |     if let (ref _x, _) = mm { }
-   |             +++
-
-error[E0382]: use of partially moved value: `mm`
-  --> $DIR/issue-53114-borrow-checks.rs:43:21
-   |
-LL |     if let (_, _y) = mm { }
-   |                -- value partially moved here
-LL |
-LL |     if let (_, _) = mm { }
-   |                     ^^ value used here after partial move
-   |
-   = note: partial move occurs because `mm.1` has type `M`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |     if let (_, ref _y) = mm { }
-   |                +++
-
-error: aborting due to 6 previous errors
-
-For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-match.rs b/tests/ui/borrowck/borrowck-move-out-from-array-match.rs
index ced4d002b384e..d2a5da66de9d4 100644
--- a/tests/ui/borrowck/borrowck-move-out-from-array-match.rs
+++ b/tests/ui/borrowck/borrowck-move-out-from-array-match.rs
@@ -42,8 +42,8 @@ fn move_out_by_const_index_and_subslice() {
         [_x, _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_y @ .., _, _] => {}
+        //~^ ERROR use of partially moved value
     }
 }
 
@@ -53,8 +53,8 @@ fn move_out_by_const_index_end_and_subslice() {
         [.., _x] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, _, _y @ ..] => {}
+        //~^ ERROR use of partially moved value
     }
 }
 
@@ -64,8 +64,8 @@ fn move_out_by_const_index_field_and_subslice() {
         [(_x, _), _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_y @ .., _, _] => {}
+        //~^ ERROR use of partially moved value
     }
 }
 
@@ -75,8 +75,8 @@ fn move_out_by_const_index_end_field_and_subslice() {
         [.., (_x, _)] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, _, _y @ ..] => {}
+        //~^ ERROR use of partially moved value
     }
 }
 
@@ -108,8 +108,8 @@ fn move_out_by_subslice_and_subslice() {
         [x @ .., _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, _y @ ..] => {}
+        //~^ ERROR use of partially moved value
     }
 }
 
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-match.stderr b/tests/ui/borrowck/borrowck-move-out-from-array-match.stderr
index 67b00c1dd90ce..d827776845e07 100644
--- a/tests/ui/borrowck/borrowck-move-out-from-array-match.stderr
+++ b/tests/ui/borrowck/borrowck-move-out-from-array-match.stderr
@@ -44,13 +44,13 @@ LL |         [_, _, (ref _x, _)] => {}
    |                 +++
 
 error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-match.rs:44:11
+  --> $DIR/borrowck-move-out-from-array-match.rs:45:10
    |
 LL |         [_x, _, _] => {}
    |          -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_y @ .., _, _] => {}
+   |          ^^ value used here after partial move
    |
    = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -59,13 +59,13 @@ LL |         [ref _x, _, _] => {}
    |          +++
 
 error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-match.rs:55:11
+  --> $DIR/borrowck-move-out-from-array-match.rs:56:16
    |
 LL |         [.., _x] => {}
    |              -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_, _, _y @ ..] => {}
+   |                ^^ value used here after partial move
    |
    = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -74,13 +74,13 @@ LL |         [.., ref _x] => {}
    |              +++
 
 error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-match.rs:66:11
+  --> $DIR/borrowck-move-out-from-array-match.rs:67:10
    |
 LL |         [(_x, _), _, _] => {}
    |           -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_y @ .., _, _] => {}
+   |          ^^ value used here after partial move
    |
    = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -89,13 +89,13 @@ LL |         [(ref _x, _), _, _] => {}
    |           +++
 
 error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-match.rs:77:11
+  --> $DIR/borrowck-move-out-from-array-match.rs:78:16
    |
 LL |         [.., (_x, _)] => {}
    |               -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_, _, _y @ ..] => {}
+   |                ^^ value used here after partial move
    |
    = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -134,13 +134,13 @@ LL |         [_, _, ref _y @ ..] => {}
    |                +++
 
 error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-match.rs:110:11
+  --> $DIR/borrowck-move-out-from-array-match.rs:111:13
    |
 LL |         [x @ .., _] => {}
    |          - value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_, _y @ ..] => {}
+   |             ^^ value used here after partial move
    |
    = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs b/tests/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs
index 97db70f34cc74..1e401b7e92e26 100644
--- a/tests/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs
+++ b/tests/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.rs
@@ -1,3 +1,4 @@
+// check-pass
 // Due to #53114, which causes a "read" of the `_` patterns,
 // the borrow-checker refuses this code, while it should probably be allowed.
 // Once the bug is fixed, the test, which is derived from a
@@ -15,7 +16,6 @@ fn move_out_from_begin_and_one_from_end() {
         [_, _, _x] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [.., _y, _] => {}
     }
 }
@@ -26,7 +26,6 @@ fn move_out_from_begin_field_and_end_field() {
         [_, _, (_x, _)] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [.., (_, _y)] => {}
     }
 }
@@ -39,7 +38,6 @@ fn move_out_by_const_index_and_subslice() {
         [_x, _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, _y @ ..] => {}
     }
 }
@@ -50,7 +48,6 @@ fn move_out_by_const_index_end_and_subslice() {
         [.., _x] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_y @ .., _] => {}
     }
 }
@@ -61,7 +58,6 @@ fn move_out_by_const_index_field_and_subslice() {
         [(_x, _), _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, _y @ ..] => {}
     }
 }
@@ -72,7 +68,6 @@ fn move_out_by_const_index_end_field_and_subslice() {
         [.., (_x, _)] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_y @ .., _] => {}
     }
 }
@@ -83,7 +78,6 @@ fn move_out_by_const_subslice_and_index_field() {
         [_, _y @ ..] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [(_x, _), _, _] => {}
     }
 }
@@ -94,7 +88,6 @@ fn move_out_by_const_subslice_and_end_index_field() {
         [_y @ .., _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [.., (_x, _)] => {}
     }
 }
@@ -107,7 +100,6 @@ fn move_out_by_subslice_and_subslice() {
         [x @ .., _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, _y @ ..] => {}
     }
 }
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr b/tests/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
deleted file mode 100644
index 47429ea3eebae..0000000000000
--- a/tests/ui/borrowck/borrowck-move-out-from-array-no-overlap-match.stderr
+++ /dev/null
@@ -1,138 +0,0 @@
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:17:11
-   |
-LL |         [_, _, _x] => {}
-   |                -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [_, _, ref _x] => {}
-   |                +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:28:11
-   |
-LL |         [_, _, (_x, _)] => {}
-   |                 -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [_, _, (ref _x, _)] => {}
-   |                 +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:41:11
-   |
-LL |         [_x, _, _] => {}
-   |          -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [ref _x, _, _] => {}
-   |          +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:52:11
-   |
-LL |         [.., _x] => {}
-   |              -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [.., ref _x] => {}
-   |              +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:63:11
-   |
-LL |         [(_x, _), _, _] => {}
-   |           -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [(ref _x, _), _, _] => {}
-   |           +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:74:11
-   |
-LL |         [.., (_x, _)] => {}
-   |               -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [.., (ref _x, _)] => {}
-   |               +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:85:11
-   |
-LL |         [_, _y @ ..] => {}
-   |             -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [_, ref _y @ ..] => {}
-   |             +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:96:11
-   |
-LL |         [_y @ .., _] => {}
-   |          -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [ref _y @ .., _] => {}
-   |          +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-no-overlap-match.rs:109:11
-   |
-LL |         [x @ .., _, _] => {}
-   |          - value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [ref x @ .., _, _] => {}
-   |          +++
-
-error: aborting due to 9 previous errors
-
-For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-use-match.rs b/tests/ui/borrowck/borrowck-move-out-from-array-use-match.rs
index 604a25cdcc1d6..fbcf126f3ea17 100644
--- a/tests/ui/borrowck/borrowck-move-out-from-array-use-match.rs
+++ b/tests/ui/borrowck/borrowck-move-out-from-array-use-match.rs
@@ -42,8 +42,8 @@ fn move_out_by_const_index_and_subslice() {
         [_x, _, _] => {}
     }
     match a {
-        //~^ ERROR [E0382]
         [ref _y @ .., _, _] => {}
+        //~^ ERROR [E0382]
     }
 }
 
@@ -53,8 +53,8 @@ fn move_out_by_const_index_end_and_subslice() {
         [.., _x] => {}
     }
     match a {
-        //~^ ERROR [E0382]
         [_, _, ref _y @ ..] => {}
+        //~^ ERROR [E0382]
     }
 }
 
@@ -64,8 +64,8 @@ fn move_out_by_const_index_field_and_subslice() {
         [(_x, _), _, _] => {}
     }
     match a {
-        //~^ ERROR [E0382]
         [ref _y @ .., _, _] => {}
+        //~^ ERROR [E0382]
     }
 }
 
@@ -75,8 +75,8 @@ fn move_out_by_const_index_end_field_and_subslice() {
         [.., (_x, _)] => {}
     }
     match a {
-        //~^ ERROR [E0382]
         [_, _, ref _y @ ..] => {}
+        //~^ ERROR [E0382]
     }
 }
 
@@ -108,8 +108,8 @@ fn move_out_by_subslice_and_subslice() {
         [x @ .., _] => {}
     }
     match a {
-        //~^ ERROR [E0382]
         [_, ref _y @ ..] => {}
+        //~^ ERROR [E0382]
     }
 }
 
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-use-match.stderr b/tests/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
index bfab13d42d2a1..da76b5c4a65f0 100644
--- a/tests/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
+++ b/tests/ui/borrowck/borrowck-move-out-from-array-use-match.stderr
@@ -43,14 +43,14 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |         [_, _, (ref _x, _)] => {}
    |                 +++
 
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-match.rs:44:11
+error[E0382]: borrow of partially moved value: `a`
+  --> $DIR/borrowck-move-out-from-array-use-match.rs:45:10
    |
 LL |         [_x, _, _] => {}
    |          -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [ref _y @ .., _, _] => {}
+   |          ^^^^^^ value borrowed here after partial move
    |
    = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -58,14 +58,14 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |         [ref _x, _, _] => {}
    |          +++
 
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-match.rs:55:11
+error[E0382]: borrow of partially moved value: `a`
+  --> $DIR/borrowck-move-out-from-array-use-match.rs:56:16
    |
 LL |         [.., _x] => {}
    |              -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_, _, ref _y @ ..] => {}
+   |                ^^^^^^ value borrowed here after partial move
    |
    = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -73,14 +73,14 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |         [.., ref _x] => {}
    |              +++
 
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-match.rs:66:11
+error[E0382]: borrow of partially moved value: `a`
+  --> $DIR/borrowck-move-out-from-array-use-match.rs:67:10
    |
 LL |         [(_x, _), _, _] => {}
    |           -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [ref _y @ .., _, _] => {}
+   |          ^^^^^^ value borrowed here after partial move
    |
    = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -88,14 +88,14 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |         [(ref _x, _), _, _] => {}
    |           +++
 
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-match.rs:77:11
+error[E0382]: borrow of partially moved value: `a`
+  --> $DIR/borrowck-move-out-from-array-use-match.rs:78:16
    |
 LL |         [.., (_x, _)] => {}
    |               -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_, _, ref _y @ ..] => {}
+   |                ^^^^^^ value borrowed here after partial move
    |
    = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
@@ -133,14 +133,14 @@ help: borrow this binding in the pattern to avoid moving the value
 LL |         [_, _, ref _y @ ..] => {}
    |                +++
 
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-match.rs:110:11
+error[E0382]: borrow of partially moved value: `a`
+  --> $DIR/borrowck-move-out-from-array-use-match.rs:111:13
    |
 LL |         [x @ .., _] => {}
    |          - value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
+...
+LL |         [_, ref _y @ ..] => {}
+   |             ^^^^^^ value borrowed here after partial move
    |
    = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
 help: borrow this binding in the pattern to avoid moving the value
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs b/tests/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs
index 017ca90b81a3f..2f6ce430b35e8 100644
--- a/tests/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs
+++ b/tests/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.rs
@@ -1,3 +1,4 @@
+// check-pass
 // Due to #53114, which causes a "read" of the `_` patterns,
 // the borrow-checker refuses this code, while it should probably be allowed.
 // Once the bug is fixed, the test, which is derived from a
@@ -15,7 +16,6 @@ fn move_out_from_begin_and_one_from_end() {
         [_, _, _x] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [.., ref _y, _] => {}
     }
 }
@@ -26,7 +26,6 @@ fn move_out_from_begin_field_and_end_field() {
         [_, _, (_x, _)] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [.., (_, ref _y)] => {}
     }
 }
@@ -39,7 +38,6 @@ fn move_out_by_const_index_and_subslice() {
         [_x, _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, ref _y @ ..] => {}
     }
 }
@@ -50,7 +48,6 @@ fn move_out_by_const_index_end_and_subslice() {
         [.., _x] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [ref _y @ .., _] => {}
     }
 }
@@ -61,7 +58,6 @@ fn move_out_by_const_index_field_and_subslice() {
         [(_x, _), _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, ref _y @ ..] => {}
     }
 }
@@ -72,7 +68,6 @@ fn move_out_by_const_index_end_field_and_subslice() {
         [.., (_x, _)] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [ref _y @ .., _] => {}
     }
 }
@@ -83,7 +78,6 @@ fn move_out_by_const_subslice_and_index_field() {
         [_, _y @ ..] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [(ref _x, _), _, _] => {}
     }
 }
@@ -94,7 +88,6 @@ fn move_out_by_const_subslice_and_end_index_field() {
         [_y @ .., _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [.., (ref _x, _)] => {}
     }
 }
@@ -107,7 +100,6 @@ fn move_out_by_subslice_and_subslice() {
         [x @ .., _, _] => {}
     }
     match a {
-        //~^ ERROR use of partially moved value
         [_, ref _y @ ..] => {}
     }
 }
diff --git a/tests/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr b/tests/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
deleted file mode 100644
index 8412c24fe6112..0000000000000
--- a/tests/ui/borrowck/borrowck-move-out-from-array-use-no-overlap-match.stderr
+++ /dev/null
@@ -1,138 +0,0 @@
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:17:11
-   |
-LL |         [_, _, _x] => {}
-   |                -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [_, _, ref _x] => {}
-   |                +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:28:11
-   |
-LL |         [_, _, (_x, _)] => {}
-   |                 -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [_, _, (ref _x, _)] => {}
-   |                 +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:41:11
-   |
-LL |         [_x, _, _] => {}
-   |          -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [ref _x, _, _] => {}
-   |          +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:52:11
-   |
-LL |         [.., _x] => {}
-   |              -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [.., ref _x] => {}
-   |              +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:63:11
-   |
-LL |         [(_x, _), _, _] => {}
-   |           -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [(ref _x, _), _, _] => {}
-   |           +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:74:11
-   |
-LL |         [.., (_x, _)] => {}
-   |               -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..].0` has type `String`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [.., (ref _x, _)] => {}
-   |               +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:85:11
-   |
-LL |         [_, _y @ ..] => {}
-   |             -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [_, ref _y @ ..] => {}
-   |             +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:96:11
-   |
-LL |         [_y @ .., _] => {}
-   |          -- value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [ref _y @ .., _] => {}
-   |          +++
-
-error[E0382]: use of partially moved value: `a`
-  --> $DIR/borrowck-move-out-from-array-use-no-overlap-match.rs:109:11
-   |
-LL |         [x @ .., _, _] => {}
-   |          - value partially moved here
-LL |     }
-LL |     match a {
-   |           ^ value used here after partial move
-   |
-   = note: partial move occurs because `a[..]` has type `(String, String)`, which does not implement the `Copy` trait
-help: borrow this binding in the pattern to avoid moving the value
-   |
-LL |         [ref x @ .., _, _] => {}
-   |          +++
-
-error: aborting due to 9 previous errors
-
-For more information about this error, try `rustc --explain E0382`.
diff --git a/tests/ui/borrowck/issue-62107-match-arm-scopes.rs b/tests/ui/borrowck/issue-62107-match-arm-scopes.rs
index 93ce34d2fe535..7dbcad9d37f51 100644
--- a/tests/ui/borrowck/issue-62107-match-arm-scopes.rs
+++ b/tests/ui/borrowck/issue-62107-match-arm-scopes.rs
@@ -1,8 +1,8 @@
 fn main() {
     let e: i32;
     match e {
-        //~^ ERROR E0381
         ref u if true => {}
+        //~^ ERROR E0381
         ref v if true => {
             let tx = 0;
             &tx;
diff --git a/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr b/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr
index 9683da919aaf3..8fe8fa710643b 100644
--- a/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr
+++ b/tests/ui/borrowck/issue-62107-match-arm-scopes.stderr
@@ -1,10 +1,11 @@
 error[E0381]: used binding `e` isn't initialized
-  --> $DIR/issue-62107-match-arm-scopes.rs:3:11
+  --> $DIR/issue-62107-match-arm-scopes.rs:4:9
    |
 LL |     let e: i32;
    |         - binding declared here but left uninitialized
 LL |     match e {
-   |           ^ `e` used here but it isn't initialized
+LL |         ref u if true => {}
+   |         ^^^^^ `e` used here but it isn't initialized
    |
 help: consider assigning a value
    |
diff --git a/tests/ui/borrowck/let_underscore_temporary.rs b/tests/ui/borrowck/let_underscore_temporary.rs
index 835cd20798f06..a5ea3b3a7ab2e 100644
--- a/tests/ui/borrowck/let_underscore_temporary.rs
+++ b/tests/ui/borrowck/let_underscore_temporary.rs
@@ -52,4 +52,42 @@ fn let_ascribe(string: &Option<&str>, mut num: Option<i32>) {
     };
 }
 
+fn matched(string: &Option<&str>, mut num: Option<i32>) {
+    match if let Some(s) = *string { s.len() } else { 0 } {
+        _ => {}
+    };
+    match if let Some(s) = &num { s } else { &0 } {
+        _ => {}
+    };
+    match if let Some(s) = &mut num {
+        *s += 1;
+        s
+    } else {
+        &mut 0
+        //~^ ERROR temporary value dropped while borrowed
+    } {
+        _ => {}
+    };
+    match if let Some(ref s) = num { s } else { &0 } {
+        _ => {}
+    };
+    match if let Some(mut s) = num {
+        s += 1;
+        s
+    } else {
+        0
+    } {
+        _ => {}
+    };
+    match if let Some(ref mut s) = num {
+        *s += 1;
+        s
+    } else {
+        &mut 0
+        //~^ ERROR temporary value dropped while borrowed
+    } {
+        _ => {}
+    };
+}
+
 fn main() {}
diff --git a/tests/ui/borrowck/let_underscore_temporary.stderr b/tests/ui/borrowck/let_underscore_temporary.stderr
index 74f3598c4d001..6bccf329181f0 100644
--- a/tests/ui/borrowck/let_underscore_temporary.stderr
+++ b/tests/ui/borrowck/let_underscore_temporary.stderr
@@ -74,6 +74,44 @@ LL | |     };
    |
    = note: consider using a `let` binding to create a longer lived value
 
-error: aborting due to 4 previous errors
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/let_underscore_temporary.rs:66:14
+   |
+LL |       match if let Some(s) = &mut num {
+   |  ___________-
+LL | |         *s += 1;
+LL | |         s
+LL | |     } else {
+LL | |         &mut 0
+   | |              ^ creates a temporary value which is freed while still in use
+LL | |
+LL | |     } {
+   | |     -
+   | |     |
+   | |_____temporary value is freed at the end of this statement
+   |       borrow later used here
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error[E0716]: temporary value dropped while borrowed
+  --> $DIR/let_underscore_temporary.rs:86:14
+   |
+LL |       match if let Some(ref mut s) = num {
+   |  ___________-
+LL | |         *s += 1;
+LL | |         s
+LL | |     } else {
+LL | |         &mut 0
+   | |              ^ creates a temporary value which is freed while still in use
+LL | |
+LL | |     } {
+   | |     -
+   | |     |
+   | |_____temporary value is freed at the end of this statement
+   |       borrow later used here
+   |
+   = note: consider using a `let` binding to create a longer lived value
+
+error: aborting due to 6 previous errors
 
 For more information about this error, try `rustc --explain E0716`.
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
index de59d743b17da..492d8718a1378 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.32bit.stderr
@@ -108,6 +108,11 @@ help: skipping check that does not even have a feature gate
    |
 LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: skipping check that does not even have a feature gate
+  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+   |
+LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors; 1 warning emitted
 
diff --git a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
index e62520ef6ad2b..f6d82d6c0ba34 100644
--- a/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
+++ b/tests/ui/consts/miri_unleashed/const_refers_to_static_cross_crate.64bit.stderr
@@ -108,6 +108,11 @@ help: skipping check that does not even have a feature gate
    |
 LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
    |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+help: skipping check that does not even have a feature gate
+  --> $DIR/const_refers_to_static_cross_crate.rs:27:20
+   |
+LL |     unsafe { match static_cross_crate::OPT_ZERO { Some(ref u) => u, None => panic!() } }
+   |                    ^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
 error: aborting due to 8 previous errors; 1 warning emitted
 
diff --git a/tests/ui/error-codes/E0396.rs b/tests/ui/error-codes/E0396.rs
index 4415b70e75ec3..383eda3d636f1 100644
--- a/tests/ui/error-codes/E0396.rs
+++ b/tests/ui/error-codes/E0396.rs
@@ -9,9 +9,11 @@ const unsafe fn unreachable() -> ! {
     const INFALLIBLE: *mut Infallible = &[] as *const [Infallible] as *const _ as _;
     match *INFALLIBLE {}
     //~^ ERROR dereferencing raw mutable pointers in constant functions is unstable
+    //~| ERROR dereferencing raw mutable pointers in constant functions is unstable
 
     const BAD: () = unsafe { match *INFALLIBLE {} };
     //~^ ERROR dereferencing raw mutable pointers in constants is unstable
+    //~| ERROR dereferencing raw mutable pointers in constants is unstable
 }
 
 fn main() {
diff --git a/tests/ui/error-codes/E0396.stderr b/tests/ui/error-codes/E0396.stderr
index 8c87f40674f2a..a84a1216e0a9d 100644
--- a/tests/ui/error-codes/E0396.stderr
+++ b/tests/ui/error-codes/E0396.stderr
@@ -16,15 +16,35 @@ LL |     match *INFALLIBLE {}
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
 
+error[E0658]: dereferencing raw mutable pointers in constant functions is unstable
+  --> $DIR/E0396.rs:10:11
+   |
+LL |     match *INFALLIBLE {}
+   |           ^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
+
+error[E0658]: dereferencing raw mutable pointers in constants is unstable
+  --> $DIR/E0396.rs:14:36
+   |
+LL |     const BAD: () = unsafe { match *INFALLIBLE {} };
+   |                                    ^^^^^^^^^^^
+   |
+   = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
+   = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+
 error[E0658]: dereferencing raw mutable pointers in constants is unstable
-  --> $DIR/E0396.rs:13:36
+  --> $DIR/E0396.rs:14:36
    |
 LL |     const BAD: () = unsafe { match *INFALLIBLE {} };
    |                                    ^^^^^^^^^^^
    |
    = note: see issue #57349 <https://github.com/rust-lang/rust/issues/57349> for more information
    = help: add `#![feature(const_mut_refs)]` to the crate attributes to enable
+   = note: duplicate diagnostic emitted due to `-Z deduplicate-diagnostics=no`
 
-error: aborting due to 3 previous errors
+error: aborting due to 5 previous errors
 
 For more information about this error, try `rustc --explain E0658`.
diff --git a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
index d27fde58244d3..087e54244b319 100644
--- a/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
+++ b/tests/ui/rfcs/rfc-2294-if-let-guard/move-guard-if-let-chain.stderr
@@ -1,5 +1,5 @@
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-guard-if-let-chain.rs:12:27
+  --> $DIR/move-guard-if-let-chain.rs:12:23
    |
 LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
@@ -7,7 +7,7 @@ LL |     let x: Box<_> = Box::new(1);
 LL |         (1, 2) if let y = x && c => (),
    |                       - value moved here
 LL |         (1, 2) if let z = x => (),
-   |                           ^ value used here after move
+   |                       ^ value used here after move
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -15,7 +15,7 @@ LL |         (1, 2) if let ref y = x && c => (),
    |                       +++
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-guard-if-let-chain.rs:36:27
+  --> $DIR/move-guard-if-let-chain.rs:36:23
    |
 LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
@@ -23,7 +23,7 @@ LL |     let x: Box<_> = Box::new(1);
 LL |         (1, _) if let y = x && c => (),
    |                       - value moved here
 LL |         (_, 2) if let z = x => (),
-   |                           ^ value used here after move
+   |                       ^ value used here after move
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
@@ -31,15 +31,13 @@ LL |         (1, _) if let ref y = x && c => (),
    |                       +++
 
 error[E0382]: use of moved value: `x`
-  --> $DIR/move-guard-if-let-chain.rs:59:36
+  --> $DIR/move-guard-if-let-chain.rs:59:32
    |
 LL |     let x: Box<_> = Box::new(1);
    |         - move occurs because `x` has type `Box<i32>`, which does not implement the `Copy` trait
 ...
 LL |         (1, _) | (_, 2) if let y = x && c => (),
-   |                                -   ^ value used here after move
-   |                                |
-   |                                value moved here
+   |                                ^ value used here after move
    |
 help: borrow this binding in the pattern to avoid moving the value
    |
diff --git a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
index e97fdcce1c18f..9dc339abc06ba 100644
--- a/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
+++ b/tests/ui/rfcs/rfc-2361-dbg-macro/dbg-macro-move-semantics.stderr
@@ -1,13 +1,14 @@
 error[E0382]: use of moved value: `a`
-  --> $DIR/dbg-macro-move-semantics.rs:9:18
+  --> $DIR/dbg-macro-move-semantics.rs:9:13
    |
 LL |     let a = NoCopy(0);
    |         - move occurs because `a` has type `NoCopy`, which does not implement the `Copy` trait
 LL |     let _ = dbg!(a);
    |             ------- value moved here
 LL |     let _ = dbg!(a);
-   |                  ^ value used here after move
+   |             ^^^^^^^ value used here after move
    |
+   = note: this error originates in the macro `dbg` (in Nightly builds, run with -Z macro-backtrace for more info)
 
 error: aborting due to previous error
 
diff --git a/tests/ui/uninhabited/diverging-guard.rs b/tests/ui/uninhabited/diverging-guard.rs
new file mode 100644
index 0000000000000..7d57cd51c2db4
--- /dev/null
+++ b/tests/ui/uninhabited/diverging-guard.rs
@@ -0,0 +1,10 @@
+// check-pass
+
+enum Void {}
+
+fn main() {
+    let x: Void;
+    match x {
+        _ if { loop {} } => (),
+    }
+}