about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_interface/src/passes.rs8
-rw-r--r--compiler/rustc_middle/src/thir.rs11
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs7
-rw-r--r--compiler/rustc_mir_build/src/build/matches/mod.rs4
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs24
-rw-r--r--compiler/rustc_mir_build/src/build/matches/test.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs25
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs27
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs3
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs13
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs7
-rw-r--r--tests/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr2
-rw-r--r--tests/ui/async-await/async-unsafe-fn-call-in-safe.rs8
-rw-r--r--tests/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr18
-rw-r--r--tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs1
-rw-r--r--tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr10
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.rs14
-rw-r--r--tests/ui/inline-const/pat-unsafe-err.thir.stderr19
-rw-r--r--tests/ui/inline-const/pat-unsafe.rs15
-rw-r--r--tests/ui/inline-const/pat-unsafe.thir.stderr26
-rw-r--r--tests/ui/pattern/non-structural-match-types.mir.stderr14
-rw-r--r--tests/ui/pattern/non-structural-match-types.rs3
-rw-r--r--tests/ui/pattern/non-structural-match-types.stderr14
-rw-r--r--tests/ui/pattern/non-structural-match-types.thir.stderr14
24 files changed, 239 insertions, 50 deletions
diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs
index 718dbaaafcc..461952ac4b4 100644
--- a/compiler/rustc_interface/src/passes.rs
+++ b/compiler/rustc_interface/src/passes.rs
@@ -775,12 +775,16 @@ fn analysis(tcx: TyCtxt<'_>, (): ()) -> Result<()> {
     rustc_hir_analysis::check_crate(tcx)?;
 
     sess.time("MIR_borrow_checking", || {
-        tcx.hir().par_body_owners(|def_id| tcx.ensure().mir_borrowck(def_id));
+        tcx.hir().par_body_owners(|def_id| {
+            // Run THIR unsafety check because it's responsible for stealing
+            // and deallocating THIR when enabled.
+            tcx.ensure().thir_check_unsafety(def_id);
+            tcx.ensure().mir_borrowck(def_id)
+        });
     });
 
     sess.time("MIR_effect_checking", || {
         for def_id in tcx.hir().body_owners() {
-            tcx.ensure().thir_check_unsafety(def_id);
             if !tcx.sess.opts.unstable_opts.thir_unsafeck {
                 rustc_mir_transform::check_unsafety::check_unsafety(tcx, def_id);
             }
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 67804998a32..80d11c8b8f8 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -636,7 +636,8 @@ impl<'tcx> Pat<'tcx> {
             Wild | Range(..) | Binding { subpattern: None, .. } | Constant { .. } | Error(_) => {}
             AscribeUserType { subpattern, .. }
             | Binding { subpattern: Some(subpattern), .. }
-            | Deref { subpattern } => subpattern.walk_(it),
+            | Deref { subpattern }
+            | InlineConstant { subpattern, .. } => subpattern.walk_(it),
             Leaf { subpatterns } | Variant { subpatterns, .. } => {
                 subpatterns.iter().for_each(|field| field.pattern.walk_(it))
             }
@@ -764,6 +765,11 @@ pub enum PatKind<'tcx> {
         value: mir::Const<'tcx>,
     },
 
+    InlineConstant {
+        value: mir::UnevaluatedConst<'tcx>,
+        subpattern: Box<Pat<'tcx>>,
+    },
+
     Range(Box<PatRange<'tcx>>),
 
     /// Matches against a slice, checking the length and extracting elements.
@@ -924,6 +930,9 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
                 write!(f, "{subpattern}")
             }
             PatKind::Constant { value } => write!(f, "{value}"),
+            PatKind::InlineConstant { value: _, ref subpattern } => {
+                write!(f, "{} (from inline const)", subpattern)
+            }
             PatKind::Range(box PatRange { lo, hi, end }) => {
                 write!(f, "{lo}")?;
                 write!(f, "{end}")?;
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index afb58438519..3da484e6f1b 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -233,16 +233,17 @@ pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'
             }
         }
         Constant { value: _ } => {}
+        InlineConstant { value: _, subpattern } => visitor.visit_pat(subpattern),
         Range(_) => {}
         Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
             for subpattern in prefix.iter() {
-                visitor.visit_pat(&subpattern);
+                visitor.visit_pat(subpattern);
             }
             if let Some(pat) = slice {
-                visitor.visit_pat(&pat);
+                visitor.visit_pat(pat);
             }
             for subpattern in suffix.iter() {
-                visitor.visit_pat(&subpattern);
+                visitor.visit_pat(subpattern);
             }
         }
         Or { pats } => {
diff --git a/compiler/rustc_mir_build/src/build/matches/mod.rs b/compiler/rustc_mir_build/src/build/matches/mod.rs
index 24c6e0eae36..1cf8c202ea4 100644
--- a/compiler/rustc_mir_build/src/build/matches/mod.rs
+++ b/compiler/rustc_mir_build/src/build/matches/mod.rs
@@ -847,6 +847,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 self.visit_primary_bindings(subpattern, subpattern_user_ty, f)
             }
 
+            PatKind::InlineConstant { ref subpattern, .. } => {
+                self.visit_primary_bindings(subpattern, pattern_user_ty.clone(), f)
+            }
+
             PatKind::Leaf { ref subpatterns } => {
                 for subpattern in subpatterns {
                     let subpattern_user_ty = pattern_user_ty.clone().leaf(subpattern.field);
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index f340feb40d4..e55daa6ee5f 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -204,6 +204,12 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 Err(match_pair)
             }
 
+            PatKind::InlineConstant { subpattern: ref pattern, value: _ } => {
+                candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
+
+                Ok(())
+            }
+
             PatKind::Range(box PatRange { lo, hi, end }) => {
                 let (range, bias) = match *lo.ty().kind() {
                     ty::Char => {
@@ -229,11 +235,21 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     // correct the comparison. This is achieved by XORing with a bias (see
                     // pattern/_match.rs for another pertinent example of this pattern).
                     //
-                    // Also, for performance, it's important to only do the second `try_to_bits` if
-                    // necessary.
-                    let lo = lo.try_to_bits(sz).unwrap() ^ bias;
+                    // Also, for performance, it's important to only do the second
+                    // `try_eval_scalar_int` if necessary.
+                    let lo = lo
+                        .try_eval_scalar_int(self.tcx, self.param_env)
+                        .unwrap()
+                        .to_bits(sz)
+                        .unwrap()
+                        ^ bias;
                     if lo <= min {
-                        let hi = hi.try_to_bits(sz).unwrap() ^ bias;
+                        let hi = hi
+                            .try_eval_scalar_int(self.tcx, self.param_env)
+                            .unwrap()
+                            .to_bits(sz)
+                            .unwrap()
+                            ^ bias;
                         if hi > max || hi == max && end == RangeEnd::Included {
                             // Irrefutable pattern match.
                             return Ok(());
diff --git a/compiler/rustc_mir_build/src/build/matches/test.rs b/compiler/rustc_mir_build/src/build/matches/test.rs
index 30ce37a7ac1..5e7db7413df 100644
--- a/compiler/rustc_mir_build/src/build/matches/test.rs
+++ b/compiler/rustc_mir_build/src/build/matches/test.rs
@@ -73,6 +73,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             PatKind::Or { .. } => bug!("or-patterns should have already been handled"),
 
             PatKind::AscribeUserType { .. }
+            | PatKind::InlineConstant { .. }
             | PatKind::Array { .. }
             | PatKind::Wild
             | PatKind::Binding { .. }
@@ -111,6 +112,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
             | PatKind::Or { .. }
             | PatKind::Binding { .. }
             | PatKind::AscribeUserType { .. }
+            | PatKind::InlineConstant { .. }
             | PatKind::Leaf { .. }
             | PatKind::Deref { .. }
             | PatKind::Error(_) => {
diff --git a/compiler/rustc_mir_build/src/build/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index d9098bac1c2..3ef173c63e7 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -53,10 +53,7 @@ pub(crate) fn closure_saved_names_of_captured_variables<'tcx>(
 }
 
 /// Construct the MIR for a given `DefId`.
-fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
-    // Ensure unsafeck and abstract const building is ran before we steal the THIR.
-    tcx.ensure_with_value()
-        .thir_check_unsafety(tcx.typeck_root_def_id(def.to_def_id()).expect_local());
+fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
     tcx.ensure_with_value().thir_abstract_const(def);
     if let Err(e) = tcx.check_match(def) {
         return construct_error(tcx, def, e);
@@ -65,9 +62,10 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
     let body = match tcx.thir_body(def) {
         Err(error_reported) => construct_error(tcx, def, error_reported),
         Ok((thir, expr)) => {
-            // We ran all queries that depended on THIR at the beginning
-            // of `mir_build`, so now we can steal it
-            let thir = thir.steal();
+            let build_mir = |thir: &Thir<'tcx>| match thir.body_type {
+                thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, thir, expr, fn_sig),
+                thir::BodyTy::Const(ty) => construct_const(tcx, def, thir, expr, ty),
+            };
 
             tcx.ensure().check_match(def);
             // this must run before MIR dump, because
@@ -76,9 +74,16 @@ fn mir_build(tcx: TyCtxt<'_>, def: LocalDefId) -> Body<'_> {
             // maybe move the check to a MIR pass?
             tcx.ensure().check_liveness(def);
 
-            match thir.body_type {
-                thir::BodyTy::Fn(fn_sig) => construct_fn(tcx, def, &thir, expr, fn_sig),
-                thir::BodyTy::Const(ty) => construct_const(tcx, def, &thir, expr, ty),
+            if tcx.sess.opts.unstable_opts.thir_unsafeck {
+                // Don't steal here if THIR unsafeck is being used. Instead
+                // steal in unsafeck. This is so that pattern inline constants
+                // can be evaluated as part of building the THIR of the parent
+                // function without a cycle.
+                build_mir(&thir.borrow())
+            } else {
+                // We ran all queries that depended on THIR at the beginning
+                // of `mir_build`, so now we can steal it
+                build_mir(&thir.steal())
             }
         }
     };
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index 2d221b826c9..f0b01e94587 100644
--- a/compiler/rustc_mir_build/src/check_unsafety.rs
+++ b/compiler/rustc_mir_build/src/check_unsafety.rs
@@ -3,7 +3,7 @@ use crate::errors::*;
 use rustc_middle::thir::visit::{self, Visitor};
 
 use rustc_hir as hir;
-use rustc_middle::mir::BorrowKind;
+use rustc_middle::mir::{BorrowKind, Const};
 use rustc_middle::thir::*;
 use rustc_middle::ty::print::with_no_trimmed_paths;
 use rustc_middle::ty::{self, ParamEnv, Ty, TyCtxt};
@@ -124,7 +124,8 @@ impl<'tcx> UnsafetyVisitor<'_, 'tcx> {
     /// Handle closures/generators/inline-consts, which is unsafecked with their parent body.
     fn visit_inner_body(&mut self, def: LocalDefId) {
         if let Ok((inner_thir, expr)) = self.tcx.thir_body(def) {
-            let inner_thir = &inner_thir.borrow();
+            let _ = self.tcx.ensure_with_value().mir_built(def);
+            let inner_thir = &inner_thir.steal();
             let hir_context = self.tcx.hir().local_def_id_to_hir_id(def);
             let mut inner_visitor = UnsafetyVisitor { thir: inner_thir, hir_context, ..*self };
             inner_visitor.visit_expr(&inner_thir[expr]);
@@ -224,6 +225,7 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 PatKind::Wild |
                 // these just wrap other patterns
                 PatKind::Or { .. } |
+                PatKind::InlineConstant { .. } |
                 PatKind::AscribeUserType { .. } |
                 PatKind::Error(_) => {}
             }
@@ -277,6 +279,24 @@ impl<'a, 'tcx> Visitor<'a, 'tcx> for UnsafetyVisitor<'a, 'tcx> {
                 visit::walk_pat(self, pat);
                 self.inside_adt = old_inside_adt;
             }
+            PatKind::Range(range) => {
+                if let Const::Unevaluated(c, _) = range.lo {
+                    if let hir::def::DefKind::InlineConst = self.tcx.def_kind(c.def) {
+                        let def_id = c.def.expect_local();
+                        self.visit_inner_body(def_id);
+                    }
+                }
+                if let Const::Unevaluated(c, _) = range.hi {
+                    if let hir::def::DefKind::InlineConst = self.tcx.def_kind(c.def) {
+                        let def_id = c.def.expect_local();
+                        self.visit_inner_body(def_id);
+                    }
+                }
+            }
+            PatKind::InlineConstant { value, .. } => {
+                let def_id = value.def.expect_local();
+                self.visit_inner_body(def_id);
+            }
             _ => {
                 visit::walk_pat(self, pat);
             }
@@ -788,7 +808,8 @@ pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
     }
 
     let Ok((thir, expr)) = tcx.thir_body(def) else { return };
-    let thir = &thir.borrow();
+    let _ = tcx.ensure_with_value().mir_built(def);
+    let thir = &thir.steal();
     // If `thir` is empty, a type error occurred, skip this body.
     if thir.exprs.is_empty() {
         return;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
index bbc0aeb66cf..06b7557c03a 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/deconstruct_pat.rs
@@ -1356,7 +1356,8 @@ impl<'p, 'tcx> DeconstructedPat<'p, 'tcx> {
         let ctor;
         let fields;
         match &pat.kind {
-            PatKind::AscribeUserType { subpattern, .. } => return mkpat(subpattern),
+            PatKind::AscribeUserType { subpattern, .. }
+            | PatKind::InlineConstant { subpattern, .. } => return mkpat(subpattern),
             PatKind::Binding { subpattern: Some(subpat), .. } => return mkpat(subpat),
             PatKind::Binding { subpattern: None, .. } | PatKind::Wild => {
                 ctor = Wildcard;
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 76ed6d2b6d7..0d066d9800b 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -93,6 +93,10 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             None => Ok((None, None)),
             Some(expr) => {
                 let (kind, ascr) = match self.lower_lit(expr) {
+                    PatKind::InlineConstant { subpattern, value } => (
+                        PatKind::Constant { value: Const::Unevaluated(value, subpattern.ty) },
+                        None,
+                    ),
                     PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
                         (kind, Some(ascription))
                     }
@@ -633,13 +637,13 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         if let Ok(Some(valtree)) =
             self.tcx.const_eval_resolve_for_typeck(self.param_env, ct, Some(span))
         {
-            self.const_to_pat(
+            let subpattern = self.const_to_pat(
                 Const::Ty(ty::Const::new_value(self.tcx, valtree, ty)),
                 id,
                 span,
                 None,
-            )
-            .kind
+            );
+            PatKind::InlineConstant { subpattern, value: uneval }
         } else {
             // If that fails, convert it to an opaque constant pattern.
             match tcx.const_eval_resolve(self.param_env, uneval, Some(span)) {
@@ -822,6 +826,9 @@ impl<'tcx> PatternFoldable<'tcx> for PatKind<'tcx> {
                 PatKind::Deref { subpattern: subpattern.fold_with(folder) }
             }
             PatKind::Constant { value } => PatKind::Constant { value },
+            PatKind::InlineConstant { value, subpattern: ref pattern } => {
+                PatKind::InlineConstant { value, subpattern: pattern.fold_with(folder) }
+            }
             PatKind::Range(ref range) => PatKind::Range(range.clone()),
             PatKind::Slice { ref prefix, ref slice, ref suffix } => PatKind::Slice {
                 prefix: prefix.fold_with(folder),
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index c957611b975..519622d450a 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -701,6 +701,13 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
                 print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl + 1);
             }
+            PatKind::InlineConstant { value, subpattern } => {
+                print_indented!(self, "InlineConstant {", depth_lvl + 1);
+                print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
+                print_indented!(self, "subpattern: ", depth_lvl + 2);
+                self.print_pat(subpattern, depth_lvl + 2);
+                print_indented!(self, "}", depth_lvl + 1);
+            }
             PatKind::Range(pat_range) => {
                 print_indented!(self, format!("Range ( {:?} )", pat_range), depth_lvl + 1);
             }
diff --git a/tests/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr b/tests/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr
index 2114fb59ba3..f9e5bf675cb 100644
--- a/tests/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr
+++ b/tests/ui/async-await/async-unsafe-fn-call-in-safe.mir.stderr
@@ -23,7 +23,7 @@ LL |     S::f();
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
 error[E0133]: call to unsafe function is unsafe and requires unsafe function or block
-  --> $DIR/async-unsafe-fn-call-in-safe.rs:24:5
+  --> $DIR/async-unsafe-fn-call-in-safe.rs:26:5
    |
 LL |     f();
    |     ^^^ call to unsafe function
diff --git a/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs b/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs
index c941dc27aa3..14cc0dc614f 100644
--- a/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs
+++ b/tests/ui/async-await/async-unsafe-fn-call-in-safe.rs
@@ -20,6 +20,10 @@ async fn g() {
 }
 
 fn main() {
-    S::f(); //[mir]~ ERROR call to unsafe function is unsafe
-    f(); //[mir]~ ERROR call to unsafe function is unsafe
+    S::f();
+    //[mir]~^ ERROR call to unsafe function is unsafe
+    //[thir]~^^ ERROR call to unsafe function `S::f` is unsafe
+    f();
+    //[mir]~^ ERROR call to unsafe function is unsafe
+    //[thir]~^^ ERROR call to unsafe function `f` is unsafe
 }
diff --git a/tests/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr b/tests/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr
index 68d97d3fd7d..ba3303fe793 100644
--- a/tests/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr
+++ b/tests/ui/async-await/async-unsafe-fn-call-in-safe.thir.stderr
@@ -14,6 +14,22 @@ LL |     f();
    |
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
-error: aborting due to 2 previous errors
+error[E0133]: call to unsafe function `S::f` is unsafe and requires unsafe function or block
+  --> $DIR/async-unsafe-fn-call-in-safe.rs:23:5
+   |
+LL |     S::f();
+   |     ^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `f` is unsafe and requires unsafe function or block
+  --> $DIR/async-unsafe-fn-call-in-safe.rs:26:5
+   |
+LL |     f();
+   |     ^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 4 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs
index afe645ae881..6c4f0a5accf 100644
--- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs
+++ b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.rs
@@ -11,4 +11,5 @@ fn main() {
     //[thir]~^^ call to unsafe function `foo` is unsafe and requires unsafe function or block
     foo();
     //[mir]~^ ERROR call to unsafe function is unsafe and requires unsafe function or block
+    //[thir]~^^ ERROR call to unsafe function `foo` is unsafe and requires unsafe function or block
 }
diff --git a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr
index b313f06539f..e6b8173eb05 100644
--- a/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr
+++ b/tests/ui/consts/const-extern-fn/const-extern-fn-requires-unsafe.thir.stderr
@@ -1,4 +1,12 @@
 error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
+  --> $DIR/const-extern-fn-requires-unsafe.rs:12:5
+   |
+LL |     foo();
+   |     ^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `foo` is unsafe and requires unsafe function or block
   --> $DIR/const-extern-fn-requires-unsafe.rs:9:17
    |
 LL |     let a: [u8; foo()];
@@ -6,6 +14,6 @@ LL |     let a: [u8; foo()];
    |
    = note: consult the function's documentation for information on how to avoid undefined behavior
 
-error: aborting due to previous error
+error: aborting due to 2 previous errors
 
 For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/inline-const/pat-unsafe-err.rs b/tests/ui/inline-const/pat-unsafe-err.rs
index e290b438c51..6df281c6d94 100644
--- a/tests/ui/inline-const/pat-unsafe-err.rs
+++ b/tests/ui/inline-const/pat-unsafe-err.rs
@@ -1,11 +1,13 @@
-// ignore-test This is currently broken
 // revisions: mir thir
+// [mir]ignore-test This is currently broken
 // [thir]compile-flags: -Z thir-unsafeck
 
 #![allow(incomplete_features)]
 #![feature(inline_const_pat)]
 
-const unsafe fn require_unsafe() -> usize { 1 }
+const unsafe fn require_unsafe() -> usize {
+    1
+}
 
 fn main() {
     match () {
@@ -14,4 +16,12 @@ fn main() {
             //~^ ERROR [E0133]
         } => (),
     }
+
+    match 1 {
+        const {
+            require_unsafe()
+            //~^ ERROR [E0133]
+        }..=4 => (),
+        _ => (),
+    }
 }
diff --git a/tests/ui/inline-const/pat-unsafe-err.thir.stderr b/tests/ui/inline-const/pat-unsafe-err.thir.stderr
new file mode 100644
index 00000000000..48a2cb4c704
--- /dev/null
+++ b/tests/ui/inline-const/pat-unsafe-err.thir.stderr
@@ -0,0 +1,19 @@
+error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
+  --> $DIR/pat-unsafe-err.rs:15:13
+   |
+LL |             require_unsafe();
+   |             ^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error[E0133]: call to unsafe function `require_unsafe` is unsafe and requires unsafe function or block
+  --> $DIR/pat-unsafe-err.rs:22:13
+   |
+LL |             require_unsafe()
+   |             ^^^^^^^^^^^^^^^^ call to unsafe function
+   |
+   = note: consult the function's documentation for information on how to avoid undefined behavior
+
+error: aborting due to 2 previous errors
+
+For more information about this error, try `rustc --explain E0133`.
diff --git a/tests/ui/inline-const/pat-unsafe.rs b/tests/ui/inline-const/pat-unsafe.rs
index bcf7f6e0180..36f8632af67 100644
--- a/tests/ui/inline-const/pat-unsafe.rs
+++ b/tests/ui/inline-const/pat-unsafe.rs
@@ -1,13 +1,15 @@
-// ignore-test This is currently broken
 // check-pass
 // revisions: mir thir
+// [mir]ignore-test This is currently broken
 // [thir]compile-flags: -Z thir-unsafeck
 
 #![allow(incomplete_features)]
 #![warn(unused_unsafe)]
 #![feature(inline_const_pat)]
 
-const unsafe fn require_unsafe() -> usize { 1 }
+const unsafe fn require_unsafe() -> usize {
+    1
+}
 
 fn main() {
     unsafe {
@@ -18,5 +20,14 @@ fn main() {
                 //~^ WARNING unnecessary `unsafe` block
             } => (),
         }
+
+        match 1 {
+            const {
+                unsafe {}
+                //~^ WARNING unnecessary `unsafe` block
+                require_unsafe()
+            }..=4 => (),
+            _ => (),
+        }
     }
 }
diff --git a/tests/ui/inline-const/pat-unsafe.thir.stderr b/tests/ui/inline-const/pat-unsafe.thir.stderr
new file mode 100644
index 00000000000..d62c87fc8f3
--- /dev/null
+++ b/tests/ui/inline-const/pat-unsafe.thir.stderr
@@ -0,0 +1,26 @@
+warning: unnecessary `unsafe` block
+  --> $DIR/pat-unsafe.rs:19:17
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe {}
+   |                 ^^^^^^ unnecessary `unsafe` block
+   |
+note: the lint level is defined here
+  --> $DIR/pat-unsafe.rs:7:9
+   |
+LL | #![warn(unused_unsafe)]
+   |         ^^^^^^^^^^^^^
+
+warning: unnecessary `unsafe` block
+  --> $DIR/pat-unsafe.rs:26:17
+   |
+LL |     unsafe {
+   |     ------ because it's nested under this `unsafe` block
+...
+LL |                 unsafe {}
+   |                 ^^^^^^ unnecessary `unsafe` block
+
+warning: 2 warnings emitted
+
diff --git a/tests/ui/pattern/non-structural-match-types.mir.stderr b/tests/ui/pattern/non-structural-match-types.mir.stderr
new file mode 100644
index 00000000000..7a9e5b7e02e
--- /dev/null
+++ b/tests/ui/pattern/non-structural-match-types.mir.stderr
@@ -0,0 +1,14 @@
+error: `{closure@$DIR/non-structural-match-types.rs:12:17: 12:19}` cannot be used in patterns
+  --> $DIR/non-structural-match-types.rs:12:9
+   |
+LL |         const { || {} } => {}
+   |         ^^^^^^^^^^^^^^^
+
+error: `{async block@$DIR/non-structural-match-types.rs:15:17: 15:25}` cannot be used in patterns
+  --> $DIR/non-structural-match-types.rs:15:9
+   |
+LL |         const { async {} } => {}
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+
diff --git a/tests/ui/pattern/non-structural-match-types.rs b/tests/ui/pattern/non-structural-match-types.rs
index fc52ee3d013..fb7779fa808 100644
--- a/tests/ui/pattern/non-structural-match-types.rs
+++ b/tests/ui/pattern/non-structural-match-types.rs
@@ -1,4 +1,7 @@
 // edition:2021
+// revisions: mir thir
+// [thir]compile-flags: -Z thir-unsafeck
+
 #![allow(incomplete_features)]
 #![allow(unreachable_code)]
 #![feature(const_async_blocks)]
diff --git a/tests/ui/pattern/non-structural-match-types.stderr b/tests/ui/pattern/non-structural-match-types.stderr
deleted file mode 100644
index f3e0665fef5..00000000000
--- a/tests/ui/pattern/non-structural-match-types.stderr
+++ /dev/null
@@ -1,14 +0,0 @@
-error: `{closure@$DIR/non-structural-match-types.rs:9:17: 9:19}` cannot be used in patterns
-  --> $DIR/non-structural-match-types.rs:9:9
-   |
-LL |         const { || {} } => {}
-   |         ^^^^^^^^^^^^^^^
-
-error: `{async block@$DIR/non-structural-match-types.rs:12:17: 12:25}` cannot be used in patterns
-  --> $DIR/non-structural-match-types.rs:12:9
-   |
-LL |         const { async {} } => {}
-   |         ^^^^^^^^^^^^^^^^^^
-
-error: aborting due to 2 previous errors
-
diff --git a/tests/ui/pattern/non-structural-match-types.thir.stderr b/tests/ui/pattern/non-structural-match-types.thir.stderr
new file mode 100644
index 00000000000..7a9e5b7e02e
--- /dev/null
+++ b/tests/ui/pattern/non-structural-match-types.thir.stderr
@@ -0,0 +1,14 @@
+error: `{closure@$DIR/non-structural-match-types.rs:12:17: 12:19}` cannot be used in patterns
+  --> $DIR/non-structural-match-types.rs:12:9
+   |
+LL |         const { || {} } => {}
+   |         ^^^^^^^^^^^^^^^
+
+error: `{async block@$DIR/non-structural-match-types.rs:15:17: 15:25}` cannot be used in patterns
+  --> $DIR/non-structural-match-types.rs:15:9
+   |
+LL |         const { async {} } => {}
+   |         ^^^^^^^^^^^^^^^^^^
+
+error: aborting due to 2 previous errors
+