about summary refs log tree commit diff
diff options
context:
space:
mode:
authorNoah Lev <camelidcamel@gmail.com>2024-06-29 21:45:22 -0700
committerNoah Lev <camelidcamel@gmail.com>2024-07-16 19:27:28 -0700
commit71f8aed510c563cc2d96405df51b410783be75c0 (patch)
treea733c2b1e7dc8b3d153b2d056b643b2e40cf05e8
parent7d356ebde329df5f38186efe3e7c5e8dabac7cb7 (diff)
downloadrust-71f8aed510c563cc2d96405df51b410783be75c0.tar.gz
rust-71f8aed510c563cc2d96405df51b410783be75c0.zip
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.
-rw-r--r--compiler/rustc_ast_lowering/src/asm.rs4
-rw-r--r--compiler/rustc_ast_lowering/src/expr.rs10
-rw-r--r--compiler/rustc_ast_lowering/src/lib.rs32
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<Box<[TraitCandidate]>>,
 
@@ -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<T>(&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,