From 1284765cfffefddbb55b3ed11f3c8be4ea04122a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Feb 2025 20:53:29 +1100 Subject: [PATCH 1/3] Rename `PatCtxt::lower_lit` to `lower_pat_expr` This matches the HIR changes in #134228, which introduced `PatExpr` to hold the subset of "expressions" that can appear in a pattern. --- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 83fef7b0de6f5..7e7fadfd18dc3 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -189,7 +189,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { // Lower the endpoint into a temporary `PatKind` that will then be // deconstructed to obtain the constant value and other data. - let mut kind: PatKind<'tcx> = self.lower_lit(expr); + let mut kind: PatKind<'tcx> = self.lower_pat_expr(expr); // Unpeel any ascription or inline-const wrapper nodes. loop { @@ -353,7 +353,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { hir::PatKind::Never => PatKind::Never, - hir::PatKind::Expr(value) => self.lower_lit(value), + hir::PatKind::Expr(value) => self.lower_pat_expr(value), hir::PatKind::Range(ref lo_expr, ref hi_expr, end) => { let (lo_expr, hi_expr) = (lo_expr.as_deref(), hi_expr.as_deref()); @@ -708,11 +708,11 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { PatKind::ExpandedConstant { subpattern, def_id: def_id.to_def_id(), is_inline: true } } - /// Converts literals, paths and negation of literals to patterns. - /// The special case for negation exists to allow things like `-128_i8` - /// which would overflow if we tried to evaluate `128_i8` and then negate - /// afterwards. - fn lower_lit(&mut self, expr: &'tcx hir::PatExpr<'tcx>) -> PatKind<'tcx> { + /// Lowers the kinds of "expression" that can appear in a HIR pattern: + /// - Paths (e.g. `FOO`, `foo::BAR`, `Option::None`) + /// - Inline const blocks (e.g. `const { 1 + 1 }`) + /// - Literals, possibly negated (e.g. `-128u8`, `"hello"`) + fn lower_pat_expr(&mut self, expr: &'tcx hir::PatExpr<'tcx>) -> PatKind<'tcx> { let (lit, neg) = match &expr.kind { hir::PatExprKind::Path(qpath) => { return self.lower_path(qpath, expr.hir_id, expr.span).kind; From c3eea531fdf00051b9aeb9a01e4f740d7e111e59 Mon Sep 17 00:00:00 2001 From: Zalathar Date: Tue, 4 Feb 2025 11:31:58 +1100 Subject: [PATCH 2/3] Clarify control-flow in `lower_path` --- .../rustc_mir_build/src/thir/pattern/mod.rs | 63 ++++++++++--------- 1 file changed, 33 insertions(+), 30 deletions(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index 7e7fadfd18dc3..e0a427d9e44a5 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -638,51 +638,54 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let ty = self.typeck_results.node_type(id); let res = self.typeck_results.qpath_res(qpath, id); - let pat_from_kind = |kind| Box::new(Pat { span, ty, kind }); - - let (def_id, is_associated_const) = match res { - Res::Def(DefKind::Const, def_id) => (def_id, false), - Res::Def(DefKind::AssocConst, def_id) => (def_id, true), + let (def_id, user_ty) = match res { + Res::Def(DefKind::Const, def_id) => (def_id, None), + Res::Def(DefKind::AssocConst, def_id) => { + (def_id, self.typeck_results.user_provided_types().get(id)) + } - _ => return pat_from_kind(self.lower_variant_or_leaf(res, id, span, ty, vec![])), + _ => { + // The path isn't the name of a constant, so it must actually + // be a unit struct or unit variant (e.g. `Option::None`). + let kind = self.lower_variant_or_leaf(res, id, span, ty, vec![]); + return Box::new(Pat { span, ty, kind }); + } }; + // Lower the named constant to a THIR pattern. let args = self.typeck_results.node_args(id); let c = ty::Const::new_unevaluated(self.tcx, ty::UnevaluatedConst { def: def_id, args }); let subpattern = self.const_to_pat(c, ty, id, span); - let pattern = Box::new(Pat { - span, - ty, - kind: PatKind::ExpandedConstant { subpattern, def_id, is_inline: false }, - }); - if !is_associated_const { - return pattern; - } + // Wrap the pattern in a marker node to indicate that it is the result + // of lowering a named constant. This marker is used for improved + // diagnostics in some situations, but has no effect at runtime. + let mut pattern = { + let kind = PatKind::ExpandedConstant { subpattern, def_id, is_inline: false }; + Box::new(Pat { span, ty, kind }) + }; - let user_provided_types = self.typeck_results.user_provided_types(); - if let Some(&user_ty) = user_provided_types.get(id) { + // If this is an associated constant with an explicit user-written + // type, add an ascription node (e.g. ` as MyTrait>::CONST`). + if let Some(&user_ty) = user_ty { let annotation = CanonicalUserTypeAnnotation { user_ty: Box::new(user_ty), span, inferred_ty: self.typeck_results.node_type(id), }; - Box::new(Pat { - span, - kind: PatKind::AscribeUserType { - subpattern: pattern, - ascription: Ascription { - annotation, - // Note that use `Contravariant` here. See the - // `variance` field documentation for details. - variance: ty::Contravariant, - }, + let kind = PatKind::AscribeUserType { + subpattern: pattern, + ascription: Ascription { + annotation, + // Note that we use `Contravariant` here. See the + // `variance` field documentation for details. + variance: ty::Contravariant, }, - ty, - }) - } else { - pattern + }; + pattern = Box::new(Pat { span, kind, ty }); } + + pattern } /// Converts inline const patterns. From 92fc085080d446ef6fd41f7c916179454bd1c43a Mon Sep 17 00:00:00 2001 From: Zalathar Date: Wed, 5 Feb 2025 21:51:05 +1100 Subject: [PATCH 3/3] More comments for `lower_inline_const` --- compiler/rustc_mir_build/src/thir/pattern/mod.rs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/compiler/rustc_mir_build/src/thir/pattern/mod.rs b/compiler/rustc_mir_build/src/thir/pattern/mod.rs index e0a427d9e44a5..22b8bfef09d26 100644 --- a/compiler/rustc_mir_build/src/thir/pattern/mod.rs +++ b/compiler/rustc_mir_build/src/thir/pattern/mod.rs @@ -688,7 +688,7 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { pattern } - /// Converts inline const patterns. + /// Lowers an inline const block (e.g. `const { 1 + 1 }`) to a pattern. fn lower_inline_const( &mut self, block: &'tcx hir::ConstBlock, @@ -708,6 +708,9 @@ impl<'a, 'tcx> PatCtxt<'a, 'tcx> { let ct = ty::UnevaluatedConst { def: def_id.to_def_id(), args }; let subpattern = self.const_to_pat(ty::Const::new_unevaluated(self.tcx, ct), ty, id, span); + + // Wrap the pattern in a marker node to indicate that it is the result + // of lowering an inline const block. PatKind::ExpandedConstant { subpattern, def_id: def_id.to_def_id(), is_inline: true } }