From 71f8aed510c563cc2d96405df51b410783be75c0 Mon Sep 17 00:00:00 2001 From: Noah Lev Date: Sat, 29 Jun 2024 21:45:22 -0700 Subject: [PATCH] Add `current_def_id_parent` to `LoweringContext` This is needed to track anon const parents properly once we implement `ConstArgKind::Path` (which requires moving anon const def-creation outside of `DefCollector`): Why do we need this in addition to [`Self::current_hir_id_owner`]? Currently (as of June 2024), anonymous constants are not HIR owners; however, they do get their own DefIds. Some of these DefIds have to be created during AST lowering, rather than def collection, because we can't tell until after name resolution whether an anonymous constant will end up instead being a [`rustc_hir::ConstArgKind::Path`]. However, to compute which generics are available to an anonymous constant nested inside another, we need to make sure that the parent is recorded as the parent anon const, not the enclosing item. So we need to track parent defs differently from HIR owners, since they will be finer-grained in the case of anon consts. --- compiler/rustc_ast_lowering/src/asm.rs | 4 ++-- compiler/rustc_ast_lowering/src/expr.rs | 10 ++------ compiler/rustc_ast_lowering/src/lib.rs | 32 ++++++++++++++++++++----- 3 files changed, 30 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index 666e7763e62..4d4a6fa8a60 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -222,10 +222,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { }; // Wrap the expression in an AnonConst. - let parent_def_id = self.current_hir_id_owner; + let parent_def_id = self.current_def_id_parent; let node_id = self.next_node_id(); self.create_def( - parent_def_id.def_id, + parent_def_id, node_id, kw::Empty, DefKind::AnonConst, diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 218fa974022..f04d0e7bece 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -377,17 +377,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let mut generic_args = ThinVec::new(); for (idx, arg) in args.into_iter().enumerate() { if legacy_args_idx.contains(&idx) { - let parent_def_id = self.current_hir_id_owner; + let parent_def_id = self.current_def_id_parent; let node_id = self.next_node_id(); // Add a definition for the in-band const def. - self.create_def( - parent_def_id.def_id, - node_id, - kw::Empty, - DefKind::AnonConst, - f.span, - ); + self.create_def(parent_def_id, node_id, kw::Empty, DefKind::AnonConst, f.span); let anon_const = AnonConst { id: node_id, value: arg }; generic_args.push(AngleBracketedArg::Arg(GenericArg::Const(anon_const))); diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 24748d2d009..8315ba6fd84 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -120,6 +120,18 @@ struct LoweringContext<'a, 'hir> { is_in_dyn_type: bool, current_hir_id_owner: hir::OwnerId, + /// Why do we need this in addition to [`Self::current_hir_id_owner`]? + /// + /// Currently (as of June 2024), anonymous constants are not HIR owners; however, + /// they do get their own DefIds. Some of these DefIds have to be created during + /// AST lowering, rather than def collection, because we can't tell until after + /// name resolution whether an anonymous constant will end up instead being a + /// [`rustc_hir::ConstArgKind::Path`]. However, to compute which generics are + /// available to an anonymous constant nested inside another, we need to make + /// sure that the parent is recorded as the parent anon const, not the enclosing + /// item. So we need to track parent defs differently from HIR owners, since they + /// will be finer-grained in the case of anon consts. + current_def_id_parent: LocalDefId, item_local_id_counter: hir::ItemLocalId, trait_map: ItemLocalMap>, @@ -162,6 +174,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { attrs: SortedMap::default(), children: Vec::default(), current_hir_id_owner: hir::CRATE_OWNER_ID, + current_def_id_parent: CRATE_DEF_ID, item_local_id_counter: hir::ItemLocalId::ZERO, node_id_to_local_id: Default::default(), trait_map: Default::default(), @@ -592,7 +605,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let _old = self.node_id_to_local_id.insert(owner, hir::ItemLocalId::ZERO); debug_assert_eq!(_old, None); - let item = f(self); + let item = self.with_def_id_parent(def_id, f); debug_assert_eq!(def_id, item.def_id().def_id); // `f` should have consumed all the elements in these vectors when constructing `item`. debug_assert!(self.impl_trait_defs.is_empty()); @@ -612,6 +625,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.children.push((def_id, hir::MaybeOwner::Owner(info))); } + fn with_def_id_parent(&mut self, parent: LocalDefId, f: impl FnOnce(&mut Self) -> T) -> T { + let current_def_id_parent = std::mem::replace(&mut self.current_def_id_parent, parent); + let result = f(self); + self.current_def_id_parent = current_def_id_parent; + result + } + /// Installs the remapping `remap` in scope while `f` is being executed. /// This causes references to the `LocalDefId` keys to be changed to /// refer to the values instead. @@ -806,7 +826,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { LifetimeRes::Fresh { param, kind, .. } => { // Late resolution delegates to us the creation of the `LocalDefId`. let _def_id = self.create_def( - self.current_hir_id_owner.def_id, + self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent? param, kw::UnderscoreLifetime, DefKind::LifetimeParam, @@ -1152,13 +1172,13 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { // Construct an AnonConst where the expr is the "ty"'s path. - let parent_def_id = self.current_hir_id_owner; + let parent_def_id = self.current_def_id_parent; let node_id = self.next_node_id(); let span = self.lower_span(ty.span); // Add a definition for the in-band const def. let def_id = self.create_def( - parent_def_id.def_id, + parent_def_id, node_id, kw::Empty, DefKind::AnonConst, @@ -1429,7 +1449,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { ); self.create_def( - self.current_hir_id_owner.def_id, + self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent? *def_node_id, ident.name, DefKind::TyParam, @@ -1637,7 +1657,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { lower_item_bounds: impl FnOnce(&mut Self) -> &'hir [hir::GenericBound<'hir>], ) -> hir::TyKind<'hir> { let opaque_ty_def_id = self.create_def( - self.current_hir_id_owner.def_id, + self.current_hir_id_owner.def_id, // FIXME: should this use self.current_def_id_parent? opaque_ty_node_id, kw::Empty, DefKind::OpaqueTy,