about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--compiler/rustc_middle/src/thir.rs15
-rw-r--r--compiler/rustc_middle/src/thir/visit.rs2
-rw-r--r--compiler/rustc_mir_build/src/build/matches/simplify.rs18
-rw-r--r--compiler/rustc_mir_build/src/build/mod.rs1
-rw-r--r--compiler/rustc_mir_build/src/check_unsafety.rs27
-rw-r--r--compiler/rustc_mir_build/src/thir/pattern/mod.rs47
-rw-r--r--compiler/rustc_mir_build/src/thir/print.rs8
7 files changed, 56 insertions, 62 deletions
diff --git a/compiler/rustc_middle/src/thir.rs b/compiler/rustc_middle/src/thir.rs
index 80d11c8b8f8..1c51c41d5a4 100644
--- a/compiler/rustc_middle/src/thir.rs
+++ b/compiler/rustc_middle/src/thir.rs
@@ -765,8 +765,19 @@ pub enum PatKind<'tcx> {
         value: mir::Const<'tcx>,
     },
 
+    /// Inline constant found while lowering a pattern.
     InlineConstant {
-        value: mir::UnevaluatedConst<'tcx>,
+        /// [LocalDefId] of the constant, we need this so that we have a
+        /// reference that can be used by unsafety checking to visit nested
+        /// unevaluated constants.
+        def: LocalDefId,
+        /// If the inline constant is used in a range pattern, this subpattern
+        /// represents the range (if both ends are inline constants, there will
+        /// be multiple InlineConstant wrappers).
+        ///
+        /// Otherwise, the actual pattern that the constant lowered to. As with
+        /// other constants, inline constants are matched structurally where
+        /// possible.
         subpattern: Box<Pat<'tcx>>,
     },
 
@@ -930,7 +941,7 @@ impl<'tcx> fmt::Display for Pat<'tcx> {
                 write!(f, "{subpattern}")
             }
             PatKind::Constant { value } => write!(f, "{value}"),
-            PatKind::InlineConstant { value: _, ref subpattern } => {
+            PatKind::InlineConstant { def: _, ref subpattern } => {
                 write!(f, "{} (from inline const)", subpattern)
             }
             PatKind::Range(box PatRange { lo, hi, end }) => {
diff --git a/compiler/rustc_middle/src/thir/visit.rs b/compiler/rustc_middle/src/thir/visit.rs
index 3da484e6f1b..d03d92c3a4b 100644
--- a/compiler/rustc_middle/src/thir/visit.rs
+++ b/compiler/rustc_middle/src/thir/visit.rs
@@ -233,7 +233,7 @@ 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),
+        InlineConstant { def: _, subpattern } => visitor.visit_pat(subpattern),
         Range(_) => {}
         Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
             for subpattern in prefix.iter() {
diff --git a/compiler/rustc_mir_build/src/build/matches/simplify.rs b/compiler/rustc_mir_build/src/build/matches/simplify.rs
index e55daa6ee5f..32573b4d53a 100644
--- a/compiler/rustc_mir_build/src/build/matches/simplify.rs
+++ b/compiler/rustc_mir_build/src/build/matches/simplify.rs
@@ -204,7 +204,7 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                 Err(match_pair)
             }
 
-            PatKind::InlineConstant { subpattern: ref pattern, value: _ } => {
+            PatKind::InlineConstant { subpattern: ref pattern, def: _ } => {
                 candidate.match_pairs.push(MatchPair::new(match_pair.place, pattern, self));
 
                 Ok(())
@@ -236,20 +236,10 @@ impl<'a, 'tcx> Builder<'a, 'tcx> {
                     // pattern/_match.rs for another pertinent example of this pattern).
                     //
                     // 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;
+                    // `try_to_bits` if necessary.
+                    let lo = lo.try_to_bits(sz).unwrap() ^ bias;
                     if lo <= min {
-                        let hi = hi
-                            .try_eval_scalar_int(self.tcx, self.param_env)
-                            .unwrap()
-                            .to_bits(sz)
-                            .unwrap()
-                            ^ bias;
+                        let hi = hi.try_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/mod.rs b/compiler/rustc_mir_build/src/build/mod.rs
index 3ef173c63e7..bd96ab453b8 100644
--- a/compiler/rustc_mir_build/src/build/mod.rs
+++ b/compiler/rustc_mir_build/src/build/mod.rs
@@ -67,7 +67,6 @@ fn mir_build<'tcx>(tcx: TyCtxt<'tcx>, def: LocalDefId) -> Body<'tcx> {
                 thir::BodyTy::Const(ty) => construct_const(tcx, def, thir, expr, ty),
             };
 
-            tcx.ensure().check_match(def);
             // this must run before MIR dump, because
             // "not all control paths return a value" is reported here.
             //
diff --git a/compiler/rustc_mir_build/src/check_unsafety.rs b/compiler/rustc_mir_build/src/check_unsafety.rs
index f0b01e94587..3e0af6c56ab 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, Const};
+use rustc_middle::mir::BorrowKind;
 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 _ = self.tcx.ensure_with_value().mir_built(def);
+            // Runs all other queries that depend on THIR.
+            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 };
@@ -279,23 +280,8 @@ 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);
+            PatKind::InlineConstant { def, .. } => {
+                self.visit_inner_body(*def);
             }
             _ => {
                 visit::walk_pat(self, pat);
@@ -808,7 +794,8 @@ pub fn thir_check_unsafety(tcx: TyCtxt<'_>, def: LocalDefId) {
     }
 
     let Ok((thir, expr)) = tcx.thir_body(def) else { return };
-    let _ = tcx.ensure_with_value().mir_built(def);
+    // Runs all other queries that depend on THIR.
+    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() {
diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
index 0d066d9800b..dd71ab1f8e5 100644
--- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs
+++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs
@@ -27,6 +27,7 @@ use rustc_middle::ty::{
     self, AdtDef, CanonicalUserTypeAnnotation, GenericArg, GenericArgsRef, Region, Ty, TyCtxt,
     TypeVisitableExt, UserType,
 };
+use rustc_span::def_id::LocalDefId;
 use rustc_span::{ErrorGuaranteed, Span, Symbol};
 use rustc_target::abi::{FieldIdx, Integer};
 
@@ -88,19 +89,21 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
     fn lower_pattern_range_endpoint(
         &mut self,
         expr: Option<&'tcx hir::Expr<'tcx>>,
-    ) -> Result<(Option<mir::Const<'tcx>>, Option<Ascription<'tcx>>), ErrorGuaranteed> {
+    ) -> Result<
+        (Option<mir::Const<'tcx>>, Option<Ascription<'tcx>>, Option<LocalDefId>),
+        ErrorGuaranteed,
+    > {
         match expr {
-            None => Ok((None, None)),
+            None => Ok((None, 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,
-                    ),
+                let (kind, ascr, inline_const) = match self.lower_lit(expr) {
+                    PatKind::InlineConstant { subpattern, def } => {
+                        (subpattern.kind, None, Some(def))
+                    }
                     PatKind::AscribeUserType { ascription, subpattern: box Pat { kind, .. } } => {
-                        (kind, Some(ascription))
+                        (kind, Some(ascription), None)
                     }
-                    kind => (kind, None),
+                    kind => (kind, None, None),
                 };
                 let value = if let PatKind::Constant { value } = kind {
                     value
@@ -110,7 +113,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                     );
                     return Err(self.tcx.sess.delay_span_bug(expr.span, msg));
                 };
-                Ok((Some(value), ascr))
+                Ok((Some(value), ascr, inline_const))
             }
         }
     }
@@ -181,8 +184,8 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
             return Err(self.tcx.sess.delay_span_bug(span, msg));
         }
 
-        let (lo, lo_ascr) = self.lower_pattern_range_endpoint(lo_expr)?;
-        let (hi, hi_ascr) = self.lower_pattern_range_endpoint(hi_expr)?;
+        let (lo, lo_ascr, lo_inline) = self.lower_pattern_range_endpoint(lo_expr)?;
+        let (hi, hi_ascr, hi_inline) = self.lower_pattern_range_endpoint(hi_expr)?;
 
         let lo = lo.unwrap_or_else(|| {
             // Unwrap is ok because the type is known to be numeric.
@@ -241,6 +244,12 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 };
             }
         }
+        for inline_const in [lo_inline, hi_inline] {
+            if let Some(def) = inline_const {
+                kind =
+                    PatKind::InlineConstant { def, subpattern: Box::new(Pat { span, ty, kind }) };
+            }
+        }
         Ok(kind)
     }
 
@@ -603,11 +612,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
         // const eval path below.
         // FIXME: investigate the performance impact of removing this.
         let lit_input = match expr.kind {
-            hir::ExprKind::Lit(ref lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
-            hir::ExprKind::Unary(hir::UnOp::Neg, ref expr) => match expr.kind {
-                hir::ExprKind::Lit(ref lit) => {
-                    Some(LitToConstInput { lit: &lit.node, ty, neg: true })
-                }
+            hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: false }),
+            hir::ExprKind::Unary(hir::UnOp::Neg, expr) => match expr.kind {
+                hir::ExprKind::Lit(lit) => Some(LitToConstInput { lit: &lit.node, ty, neg: true }),
                 _ => None,
             },
             _ => None,
@@ -643,7 +650,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> {
                 span,
                 None,
             );
-            PatKind::InlineConstant { subpattern, value: uneval }
+            PatKind::InlineConstant { subpattern, def: def_id }
         } else {
             // If that fails, convert it to an opaque constant pattern.
             match tcx.const_eval_resolve(self.param_env, uneval, Some(span)) {
@@ -826,8 +833,8 @@ 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::InlineConstant { def, subpattern: ref pattern } => {
+                PatKind::InlineConstant { def, subpattern: pattern.fold_with(folder) }
             }
             PatKind::Range(ref range) => PatKind::Range(range.clone()),
             PatKind::Slice { ref prefix, ref slice, ref suffix } => PatKind::Slice {
diff --git a/compiler/rustc_mir_build/src/thir/print.rs b/compiler/rustc_mir_build/src/thir/print.rs
index 519622d450a..c3b2309b7cd 100644
--- a/compiler/rustc_mir_build/src/thir/print.rs
+++ b/compiler/rustc_mir_build/src/thir/print.rs
@@ -692,7 +692,7 @@ impl<'a, 'tcx> ThirPrinter<'a, 'tcx> {
             }
             PatKind::Deref { subpattern } => {
                 print_indented!(self, "Deref { ", depth_lvl + 1);
-                print_indented!(self, "subpattern: ", depth_lvl + 2);
+                print_indented!(self, "subpattern:", depth_lvl + 2);
                 self.print_pat(subpattern, depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl + 1);
             }
@@ -701,10 +701,10 @@ 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 } => {
+            PatKind::InlineConstant { def, subpattern } => {
                 print_indented!(self, "InlineConstant {", depth_lvl + 1);
-                print_indented!(self, format!("value: {:?}", value), depth_lvl + 2);
-                print_indented!(self, "subpattern: ", depth_lvl + 2);
+                print_indented!(self, format!("def: {:?}", def), depth_lvl + 2);
+                print_indented!(self, "subpattern:", depth_lvl + 2);
                 self.print_pat(subpattern, depth_lvl + 2);
                 print_indented!(self, "}", depth_lvl + 1);
             }