From 400ebb697fbeccc2ed29ae6340b21a8aa7c6baf0 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 19 Mar 2025 16:47:27 +0000 Subject: [PATCH 1/8] Remove a needless mutability --- compiler/rustc_ast_lowering/src/lib.rs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index c5ec53af6e505..0cebac21a207f 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -289,7 +289,7 @@ impl ResolverAstLowering { /// /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring /// should appear at the enclosing `PolyTraitRef`. - fn extra_lifetime_params(&mut self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { + fn extra_lifetime_params(&self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default() } } From 5ec32d068c56a76741f1c18dcff7480b2c4db402 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Mon, 24 Mar 2025 14:39:35 +0000 Subject: [PATCH 2/8] Split trait item resolving into its own method --- compiler/rustc_resolve/src/late.rs | 104 ++++++++++++++--------------- 1 file changed, 52 insertions(+), 52 deletions(-) diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index f72abaa37201e..1805a77cba188 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3254,6 +3254,14 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let trait_assoc_items = replace(&mut self.diag_metadata.current_trait_assoc_items, Some(trait_items)); + for item in trait_items { + self.resolve_trait_item(item); + } + + self.diag_metadata.current_trait_assoc_items = trait_assoc_items; + } + + fn resolve_trait_item(&mut self, item: &'ast Item) { let walk_assoc_item = |this: &mut Self, generics: &Generics, kind, item: &'ast AssocItem| { this.with_generic_param_rib( @@ -3266,30 +3274,25 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { ); }; - for item in trait_items { - self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id)); - match &item.kind { - AssocItemKind::Const(box ast::ConstItem { - generics, - ty, - rhs_kind, - define_opaque, - .. - }) => { - self.with_generic_param_rib( - &generics.params, - RibKind::AssocItem, - item.id, - LifetimeBinderKind::ConstItem, - generics.span, - |this| { - this.with_lifetime_rib( - LifetimeRibKind::StaticIfNoLifetimeInScope { - lint_id: item.id, - emit_lint: false, - }, - |this| { - this.visit_generics(generics); + self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id)); + match &item.kind { + AssocItemKind::Const(box ast::ConstItem { + generics, ty, rhs_kind, define_opaque, .. + }) => { + self.with_generic_param_rib( + &generics.params, + RibKind::AssocItem, + item.id, + LifetimeBinderKind::ConstItem, + generics.span, + |this| { + this.with_lifetime_rib( + LifetimeRibKind::StaticIfNoLifetimeInScope { + lint_id: item.id, + emit_lint: false, + }, + |this| { + this.visit_generics(generics); if rhs_kind.is_type_const() && !this.r.tcx.features().generic_const_parameter_types() { @@ -3302,7 +3305,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }) }); } else { - this.visit_ty(ty); + this.visit_ty(ty); } // Only impose the restrictions of `ConstRibKind` for an @@ -3319,34 +3322,31 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, ); - self.resolve_define_opaques(define_opaque); - } - AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => { - walk_assoc_item(self, generics, LifetimeBinderKind::Function, item); - - self.resolve_define_opaques(define_opaque); - } - AssocItemKind::Delegation(delegation) => { - self.with_generic_param_rib( - &[], - RibKind::AssocItem, - item.id, - LifetimeBinderKind::Function, - delegation.path.segments.last().unwrap().ident.span, - |this| this.resolve_delegation(delegation, item.id, false, &item.attrs), - ); - } - AssocItemKind::Type(box TyAlias { generics, .. }) => self - .with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { - walk_assoc_item(this, generics, LifetimeBinderKind::Item, item) - }), - AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => { - panic!("unexpanded macro in resolve!") - } - }; - } + self.resolve_define_opaques(define_opaque); + } + AssocItemKind::Fn(box Fn { generics, define_opaque, .. }) => { + walk_assoc_item(self, generics, LifetimeBinderKind::Function, item); - self.diag_metadata.current_trait_assoc_items = trait_assoc_items; + self.resolve_define_opaques(define_opaque); + } + AssocItemKind::Delegation(delegation) => { + self.with_generic_param_rib( + &[], + RibKind::AssocItem, + item.id, + LifetimeBinderKind::Function, + delegation.path.segments.last().unwrap().ident.span, + |this| this.resolve_delegation(delegation, item.id, false, &item.attrs), + ); + } + AssocItemKind::Type(box TyAlias { generics, .. }) => self + .with_lifetime_rib(LifetimeRibKind::AnonymousReportError, |this| { + walk_assoc_item(this, generics, LifetimeBinderKind::Item, item) + }), + AssocItemKind::MacCall(_) | AssocItemKind::DelegationMac(..) => { + panic!("unexpanded macro in resolve!") + } + }; } /// This is called to resolve a trait reference from an `impl` (i.e., `impl Trait for Foo`). From c98471e358c27f964eeb462c2c7f7416723ce917 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 20 Mar 2025 14:45:16 +0000 Subject: [PATCH 3/8] Replace extension trait with wrapper struct --- compiler/rustc_ast_lowering/src/asm.rs | 4 +- compiler/rustc_ast_lowering/src/delegation.rs | 31 +++++----- compiler/rustc_ast_lowering/src/expr.rs | 4 +- compiler/rustc_ast_lowering/src/item.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 40 +++++++------ compiler/rustc_ast_lowering/src/pat.rs | 2 +- compiler/rustc_ast_lowering/src/path.rs | 2 +- compiler/rustc_resolve/src/late.rs | 58 ++++++++++--------- 8 files changed, 75 insertions(+), 68 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/asm.rs b/compiler/rustc_ast_lowering/src/asm.rs index a7bf1c99a7e23..cf7291722d37b 100644 --- a/compiler/rustc_ast_lowering/src/asm.rs +++ b/compiler/rustc_ast_lowering/src/asm.rs @@ -19,9 +19,7 @@ use super::errors::{ InvalidRegisterClass, RegisterClassOnlyClobber, RegisterClassOnlyClobberStable, RegisterConflict, }; -use crate::{ - AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode, ResolverAstLoweringExt, -}; +use crate::{AllowReturnTypeNotation, ImplTraitContext, ImplTraitPosition, ParamMode}; impl<'a, 'hir> LoweringContext<'a, 'hir> { pub(crate) fn lower_inline_asm( diff --git a/compiler/rustc_ast_lowering/src/delegation.rs b/compiler/rustc_ast_lowering/src/delegation.rs index cccfb112ec2b7..d9d5c481bc7a3 100644 --- a/compiler/rustc_ast_lowering/src/delegation.rs +++ b/compiler/rustc_ast_lowering/src/delegation.rs @@ -50,7 +50,7 @@ use rustc_hir::Target; use rustc_hir::attrs::{AttributeKind, InlineAttr}; use rustc_hir::def_id::{DefId, LocalDefId}; use rustc_middle::span_bug; -use rustc_middle::ty::{Asyncness, DelegationAttrs, DelegationFnSigAttrs, ResolverAstLowering}; +use rustc_middle::ty::{Asyncness, DelegationAttrs, DelegationFnSigAttrs}; use rustc_span::symbol::kw; use rustc_span::{DUMMY_SP, Ident, Span, Symbol}; use smallvec::SmallVec; @@ -58,7 +58,7 @@ use {rustc_ast as ast, rustc_hir as hir}; use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode}; use crate::errors::{CycleInDelegationSignatureResolution, UnresolvedDelegationCallee}; -use crate::{AllowReturnTypeNotation, ImplTraitPosition, ResolverAstLoweringExt}; +use crate::{AllowReturnTypeNotation, ImplTraitPosition, PerOwnerResolver}; pub(crate) struct DelegationResults<'hir> { pub body_id: hir::BodyId, @@ -136,6 +136,7 @@ impl<'hir> LoweringContext<'_, 'hir> { DefKind::AssocFn => match def_id.as_local() { Some(local_def_id) => self .resolver + .general .delegation_fn_sigs .get(&local_def_id) .is_some_and(|sig| sig.has_self), @@ -154,7 +155,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Delegation can be unresolved in illegal places such as function bodies in extern blocks (see #151356) let ids = if let Some(delegation_info) = - self.resolver.delegation_infos.get(&self.local_def_id(item_id)) + self.resolver.general.delegation_infos.get(&self.local_def_id(item_id)) { self.get_delegation_ids(delegation_info.resolution_node, span) } else { @@ -306,10 +307,10 @@ impl<'hir> LoweringContext<'_, 'hir> { fn get_attrs(&self, local_id: LocalDefId) -> &DelegationAttrs { // local_id can correspond either to a function or other delegation - if let Some(fn_sig) = self.resolver.delegation_fn_sigs.get(&local_id) { + if let Some(fn_sig) = self.resolver.general.delegation_fn_sigs.get(&local_id) { &fn_sig.attrs } else { - &self.resolver.delegation_infos[&local_id].attrs + &self.resolver.general.delegation_infos[&local_id].attrs } } @@ -340,7 +341,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // it means that we refer to another delegation as a callee, so in order to obtain // a signature DefId we obtain NodeId of the callee delegation and try to get signature from it. if let Some(local_id) = def_id.as_local() - && let Some(delegation_info) = self.resolver.delegation_infos.get(&local_id) + && let Some(delegation_info) = self.resolver.general.delegation_infos.get(&local_id) { node_id = delegation_info.resolution_node; if visited.contains(&node_id) { @@ -374,7 +375,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // Function parameter count, including C variadic `...` if present. fn param_count(&self, def_id: DefId) -> (usize, bool /*c_variadic*/) { if let Some(local_sig_id) = def_id.as_local() { - match self.resolver.delegation_fn_sigs.get(&local_sig_id) { + match self.resolver.general.delegation_fn_sigs.get(&local_sig_id) { Some(sig) => (sig.param_count, sig.c_variadic), None => (0, false), } @@ -422,7 +423,7 @@ impl<'hir> LoweringContext<'_, 'hir> { span: Span, ) -> hir::FnSig<'hir> { let header = if let Some(local_sig_id) = sig_id.as_local() { - match self.resolver.delegation_fn_sigs.get(&local_sig_id) { + match self.resolver.general.delegation_fn_sigs.get(&local_sig_id) { Some(sig) => { let parent = self.tcx.parent(sig_id); // HACK: we override the default safety instead of generating attributes from the ether. @@ -531,7 +532,7 @@ impl<'hir> LoweringContext<'_, 'hir> { && idx == 0 { let mut self_resolver = SelfResolver { - resolver: this.resolver, + resolver: &mut this.resolver, path_id: delegation.id, self_param_id: pat_node_id, }; @@ -711,25 +712,25 @@ impl<'hir> LoweringContext<'_, 'hir> { } } -struct SelfResolver<'a> { - resolver: &'a mut ResolverAstLowering, +struct SelfResolver<'a, 'b> { + resolver: &'b mut PerOwnerResolver<'a>, path_id: NodeId, self_param_id: NodeId, } -impl<'a> SelfResolver<'a> { +impl SelfResolver<'_, '_> { fn try_replace_id(&mut self, id: NodeId) { - if let Some(res) = self.resolver.partial_res_map.get(&id) + if let Some(res) = self.resolver.general.partial_res_map.get(&id) && let Some(Res::Local(sig_id)) = res.full_res() && sig_id == self.path_id { let new_res = PartialRes::new(Res::Local(self.self_param_id)); - self.resolver.partial_res_map.insert(id, new_res); + self.resolver.general.partial_res_map.insert(id, new_res); } } } -impl<'ast, 'a> Visitor<'ast> for SelfResolver<'a> { +impl<'ast> Visitor<'ast> for SelfResolver<'_, '_> { fn visit_id(&mut self, id: NodeId) { self.try_replace_id(id); } diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index b034e250b58d0..9bce0fbfd84c2 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -25,9 +25,7 @@ use super::errors::{ InclusiveRangeWithNoEnd, MatchArmWithNoBody, NeverPatternWithBody, NeverPatternWithGuard, UnderscoreExprLhsAssign, }; -use super::{ - GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt, -}; +use super::{GenericArgsMode, ImplTraitContext, LoweringContext, ParamMode}; use crate::errors::{InvalidLegacyConstGenericArg, UseConstGenericArg, YieldInClosure}; use crate::{AllowReturnTypeNotation, FnDeclKind, ImplTraitPosition, TryBlockScope}; diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 8ae117f62786f..74e38e68a27ef 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -22,7 +22,7 @@ use super::errors::{InvalidAbi, InvalidAbiSuggestion, TupleStructWithDefault, Un use super::stability::{enabled_names, gate_unstable_abi}; use super::{ AstOwner, FnDeclKind, ImplTraitContext, ImplTraitPosition, LoweringContext, ParamMode, - RelaxedBoundForbiddenReason, RelaxedBoundPolicy, ResolverAstLoweringExt, + RelaxedBoundForbiddenReason, RelaxedBoundPolicy, }; pub(super) struct ItemLowerer<'a, 'hir> { diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0cebac21a207f..0d0a876cd57ba 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -57,7 +57,6 @@ use rustc_hir::{ LifetimeSyntax, ParamName, Target, TraitCandidate, find_attr, }; use rustc_index::{Idx, IndexSlice, IndexVec}; -use rustc_macros::extension; use rustc_middle::span_bug; use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; use rustc_session::parse::add_feature_diagnostics; @@ -90,7 +89,7 @@ pub mod stability; struct LoweringContext<'a, 'hir> { tcx: TyCtxt<'hir>, - resolver: &'a mut ResolverAstLowering, + resolver: PerOwnerResolver<'a>, disambiguator: DisambiguatorState, /// Used to allocate HIR nodes. @@ -155,7 +154,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Self { // Pseudo-globals. tcx, - resolver, + resolver: PerOwnerResolver { general: resolver }, disambiguator: DisambiguatorState::new(), arena: tcx.hir_arena, @@ -233,8 +232,11 @@ impl SpanLowerer { } } -#[extension(trait ResolverAstLoweringExt)] -impl ResolverAstLowering { +pub(crate) struct PerOwnerResolver<'a> { + pub general: &'a mut ResolverAstLowering, +} + +impl PerOwnerResolver<'_> { fn legacy_const_generic_args(&self, expr: &Expr, tcx: TyCtxt<'_>) -> Option> { let ExprKind::Path(None, path) = &expr.kind else { return None; @@ -246,7 +248,7 @@ impl ResolverAstLowering { return None; } - let def_id = self.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; + let def_id = self.general.partial_res_map.get(&expr.id)?.full_res()?.opt_def_id()?; // We only support cross-crate argument rewriting. Uses // within the same crate should be updated to use the new @@ -264,22 +266,22 @@ impl ResolverAstLowering { } fn get_partial_res(&self, id: NodeId) -> Option { - self.partial_res_map.get(&id).copied() + self.general.partial_res_map.get(&id).copied() } /// Obtains per-namespace resolutions for `use` statement with the given `NodeId`. fn get_import_res(&self, id: NodeId) -> PerNS>> { - self.import_res_map.get(&id).copied().unwrap_or_default() + self.general.import_res_map.get(&id).copied().unwrap_or_default() } /// Obtains resolution for a label with the given `NodeId`. fn get_label_res(&self, id: NodeId) -> Option { - self.label_res_map.get(&id).copied() + self.general.label_res_map.get(&id).copied() } /// Obtains resolution for a lifetime with the given `NodeId`. fn get_lifetime_res(&self, id: NodeId) -> Option { - self.lifetimes_res_map.get(&id).copied() + self.general.lifetimes_res_map.get(&id).copied() } /// Obtain the list of lifetimes parameters to add to an item. @@ -290,7 +292,7 @@ impl ResolverAstLowering { /// The extra lifetimes that appear from the parenthesized `Fn`-trait desugaring /// should appear at the enclosing `PolyTraitRef`. fn extra_lifetime_params(&self, id: NodeId) -> Vec<(Ident, NodeId, LifetimeRes)> { - self.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default() + self.general.extra_lifetime_params_map.get(&id).cloned().unwrap_or_default() } } @@ -590,22 +592,22 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); - self.resolver.node_id_to_def_id.insert(node_id, def_id); + self.resolver.general.node_id_to_def_id.insert(node_id, def_id); def_id } fn next_node_id(&mut self) -> NodeId { - let start = self.resolver.next_node_id; + let start = self.resolver.general.next_node_id; let next = start.as_u32().checked_add(1).expect("input too large; ran out of NodeIds"); - self.resolver.next_node_id = ast::NodeId::from_u32(next); + self.resolver.general.next_node_id = ast::NodeId::from_u32(next); start } /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name /// resolver (if any). fn opt_local_def_id(&self, node: NodeId) -> Option { - self.resolver.node_id_to_def_id.get(&node).copied() + self.resolver.general.node_id_to_def_id.get(&node).copied() } fn local_def_id(&self, node: NodeId) -> LocalDefId { @@ -734,7 +736,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.children.push((def_id, hir::MaybeOwner::NonOwner(hir_id))); } - if let Some(traits) = self.resolver.trait_map.remove(&ast_node_id) { + if let Some(traits) = self.resolver.general.trait_map.remove(&ast_node_id) { self.trait_map.insert(hir_id.local_id, traits.into_boxed_slice()); } @@ -1744,7 +1746,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { inputs, output, c_variadic, - lifetime_elision_allowed: self.resolver.lifetime_elision_allowed.contains(&fn_node_id), + lifetime_elision_allowed: self + .resolver + .general + .lifetime_elision_allowed + .contains(&fn_node_id), implicit_self: decl.inputs.get(0).map_or(hir::ImplicitSelfKind::None, |arg| { let is_mutable_pat = matches!( arg.pat.kind, diff --git a/compiler/rustc_ast_lowering/src/pat.rs b/compiler/rustc_ast_lowering/src/pat.rs index e066bce95158d..266fb72eec1e7 100644 --- a/compiler/rustc_ast_lowering/src/pat.rs +++ b/compiler/rustc_ast_lowering/src/pat.rs @@ -12,7 +12,7 @@ use rustc_span::{DesugaringKind, Ident, Span}; use super::errors::{ ArbitraryExpressionInPattern, ExtraDoubleDot, MisplacedDoubleDot, SubTupleBinding, }; -use super::{ImplTraitContext, LoweringContext, ParamMode, ResolverAstLoweringExt}; +use super::{ImplTraitContext, LoweringContext, ParamMode}; use crate::{AllowReturnTypeNotation, ImplTraitPosition}; impl<'a, 'hir> LoweringContext<'a, 'hir> { diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index bfb42efb684f1..edea7db3dc087 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -16,7 +16,7 @@ use super::errors::{ }; use super::{ AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition, - LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, + LifetimeRes, LoweringContext, ParamMode, }; impl<'a, 'hir> LoweringContext<'a, 'hir> { diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 1805a77cba188..84aeb50abd96f 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -3277,7 +3277,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.resolve_doc_links(&item.attrs, MaybeExported::Ok(item.id)); match &item.kind { AssocItemKind::Const(box ast::ConstItem { - generics, ty, rhs_kind, define_opaque, .. + generics, + ty, + rhs_kind, + define_opaque, + .. }) => { self.with_generic_param_rib( &generics.params, @@ -3293,34 +3297,34 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }, |this| { this.visit_generics(generics); - if rhs_kind.is_type_const() - && !this.r.tcx.features().generic_const_parameter_types() - { - this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { - this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { - this.with_lifetime_rib( - LifetimeRibKind::ConstParamTy, - |this| this.visit_ty(ty), - ) - }) - }); - } else { + if rhs_kind.is_type_const() + && !this.r.tcx.features().generic_const_parameter_types() + { + this.with_rib(TypeNS, RibKind::ConstParamTy, |this| { + this.with_rib(ValueNS, RibKind::ConstParamTy, |this| { + this.with_lifetime_rib( + LifetimeRibKind::ConstParamTy, + |this| this.visit_ty(ty), + ) + }) + }); + } else { this.visit_ty(ty); - } + } - // Only impose the restrictions of `ConstRibKind` for an - // actual constant expression in a provided default. - // - // We allow arbitrary const expressions inside of associated consts, - // even if they are potentially not const evaluatable. - // - // Type parameters can already be used and as associated consts are - // not used as part of the type system, this is far less surprising. - this.resolve_const_item_rhs(rhs_kind, None); - }, - ) - }, - ); + // Only impose the restrictions of `ConstRibKind` for an + // actual constant expression in a provided default. + // + // We allow arbitrary const expressions inside of associated consts, + // even if they are potentially not const evaluatable. + // + // Type parameters can already be used and as associated consts are + // not used as part of the type system, this is far less surprising. + this.resolve_const_item_rhs(rhs_kind, None); + }, + ) + }, + ); self.resolve_define_opaques(define_opaque); } From a5da76544075f519569d1197d0e2924f1a5bbed2 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 17 Feb 2026 11:57:28 +0000 Subject: [PATCH 4/8] Split the resolver tables into per-owner tables, starting with `node_id_to_def_id` --- compiler/rustc_ast_lowering/src/item.rs | 5 +- compiler/rustc_ast_lowering/src/lib.rs | 73 +++++++++++-- compiler/rustc_expand/src/base.rs | 7 ++ compiler/rustc_expand/src/expand.rs | 33 ++++-- compiler/rustc_interface/src/passes.rs | 2 +- compiler/rustc_middle/src/ty/mod.rs | 17 +++- compiler/rustc_passes/src/lang_items.rs | 6 +- compiler/rustc_resolve/src/def_collector.rs | 107 ++++++++++++++------ compiler/rustc_resolve/src/late.rs | 62 +++++++++--- compiler/rustc_resolve/src/lib.rs | 87 ++++++++++++---- compiler/rustc_resolve/src/macros.rs | 30 +++++- 11 files changed, 330 insertions(+), 99 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index 74e38e68a27ef..687478ee0cf36 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -77,7 +77,10 @@ impl<'a, 'hir> ItemLowerer<'a, 'hir> { match node { AstOwner::NonOwner => {} AstOwner::Crate(c) => { - assert_eq!(self.resolver.node_id_to_def_id[&CRATE_NODE_ID], CRATE_DEF_ID); + assert_eq!( + self.resolver.owners[&CRATE_NODE_ID].node_id_to_def_id[&CRATE_NODE_ID], + CRATE_DEF_ID + ); self.with_lctx(CRATE_NODE_ID, |lctx| { let module = lctx.lower_mod(&c.items, &c.spans); // FIXME(jdonszelman): is dummy span ever a problem here? diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 0d0a876cd57ba..26bbc2ceea689 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -58,7 +58,7 @@ use rustc_hir::{ }; use rustc_index::{Idx, IndexSlice, IndexVec}; use rustc_middle::span_bug; -use rustc_middle::ty::{ResolverAstLowering, TyCtxt}; +use rustc_middle::ty::{PerOwnerResolverData, ResolverAstLowering, TyCtxt}; use rustc_session::parse::add_feature_diagnostics; use rustc_span::symbol::{Ident, Symbol, kw, sym}; use rustc_span::{DUMMY_SP, DesugaringKind, Span}; @@ -154,7 +154,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { Self { // Pseudo-globals. tcx, - resolver: PerOwnerResolver { general: resolver }, + resolver: PerOwnerResolver { + general: resolver, + item: PerOwnerResolverData::new(DUMMY_NODE_ID), + }, disambiguator: DisambiguatorState::new(), arena: tcx.hir_arena, @@ -234,6 +237,15 @@ impl SpanLowerer { pub(crate) struct PerOwnerResolver<'a> { pub general: &'a mut ResolverAstLowering, + pub item: PerOwnerResolverData, +} + +impl<'a> std::ops::Deref for PerOwnerResolver<'a> { + type Target = PerOwnerResolverData; + + fn deref(&self) -> &Self::Target { + &self.item + } } impl PerOwnerResolver<'_> { @@ -434,10 +446,14 @@ enum TryBlockScope { } fn index_crate<'a>( - node_id_to_def_id: &NodeMap, + owners: &NodeMap, krate: &'a Crate, ) -> IndexVec> { - let mut indexer = Indexer { node_id_to_def_id, index: IndexVec::new() }; + let mut indexer = Indexer { + owners, + node_id_to_def_id: &owners[&CRATE_NODE_ID].node_id_to_def_id, + index: IndexVec::new(), + }; *indexer.index.ensure_contains_elem(CRATE_DEF_ID, || AstOwner::NonOwner) = AstOwner::Crate(krate); visit::walk_crate(&mut indexer, krate); @@ -445,6 +461,7 @@ fn index_crate<'a>( struct Indexer<'s, 'a> { node_id_to_def_id: &'s NodeMap, + owners: &'s NodeMap, index: IndexVec>, } @@ -455,23 +472,38 @@ fn index_crate<'a>( } fn visit_item(&mut self, item: &'a ast::Item) { + let old = std::mem::replace( + &mut self.node_id_to_def_id, + &self.owners[&item.id].node_id_to_def_id, + ); let def_id = self.node_id_to_def_id[&item.id]; *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::Item(item); - visit::walk_item(self, item) + visit::walk_item(self, item); + self.node_id_to_def_id = old; } fn visit_assoc_item(&mut self, item: &'a ast::AssocItem, ctxt: visit::AssocCtxt) { + let old = std::mem::replace( + &mut self.node_id_to_def_id, + &self.owners[&item.id].node_id_to_def_id, + ); let def_id = self.node_id_to_def_id[&item.id]; *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::AssocItem(item, ctxt); visit::walk_assoc_item(self, item, ctxt); + self.node_id_to_def_id = old; } fn visit_foreign_item(&mut self, item: &'a ast::ForeignItem) { + let old = std::mem::replace( + &mut self.node_id_to_def_id, + &self.owners[&item.id].node_id_to_def_id, + ); let def_id = self.node_id_to_def_id[&item.id]; *self.index.ensure_contains_elem(def_id, || AstOwner::NonOwner) = AstOwner::ForeignItem(item); visit::walk_item(self, item); + self.node_id_to_def_id = old; } } } @@ -508,7 +540,7 @@ pub fn lower_to_hir(tcx: TyCtxt<'_>, (): ()) -> hir::Crate<'_> { tcx.ensure_done().get_lang_items(()); let (mut resolver, krate) = tcx.resolver_for_lowering().steal(); - let ast_index = index_crate(&resolver.node_id_to_def_id, &krate); + let ast_index = index_crate(&resolver.owners, &krate); let mut owners = IndexVec::from_fn_n( |_| hir::MaybeOwner::Phantom, tcx.definitions_untracked().def_index_count(), @@ -592,7 +624,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); - self.resolver.general.node_id_to_def_id.insert(node_id, def_id); + self.resolver.item.node_id_to_def_id.insert(node_id, def_id); def_id } @@ -607,16 +639,29 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { /// Given the id of some node in the AST, finds the `LocalDefId` associated with it by the name /// resolver (if any). fn opt_local_def_id(&self, node: NodeId) -> Option { - self.resolver.general.node_id_to_def_id.get(&node).copied() + self.resolver.node_id_to_def_id.get(&node).copied() } fn local_def_id(&self, node: NodeId) -> LocalDefId { - self.opt_local_def_id(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) + self.opt_local_def_id(node).unwrap_or_else(|| { + self.resolver.general.owners.items().any(|(id, items)| { + items.node_id_to_def_id.items().any(|(node_id, def_id)| { + if *node_id == node { + panic!( + "{def_id:?} ({node_id}) was found in {:?} ({id})", + items.node_id_to_def_id.get(id), + ) + } + false + }) + }); + panic!("no entry for node id: `{node:?}`"); + }) } /// Given the id of an owner node in the AST, returns the corresponding `OwnerId`. fn owner_id(&self, node: NodeId) -> hir::OwnerId { - hir::OwnerId { def_id: self.local_def_id(node) } + hir::OwnerId { def_id: self.resolver.general.owners[&node].node_id_to_def_id[&node] } } /// Freshen the `LoweringContext` and ready it to lower a nested item. @@ -635,6 +680,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let current_attrs = std::mem::take(&mut self.attrs); let current_bodies = std::mem::take(&mut self.bodies); let current_define_opaque = std::mem::take(&mut self.define_opaque); + let current_ast_owner = std::mem::replace( + &mut self.resolver.item, + self.resolver.general.owners.remove(&owner).unwrap(), + ); let current_ident_and_label_to_local_id = std::mem::take(&mut self.ident_and_label_to_local_id); @@ -682,6 +731,10 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.impl_trait_bounds = current_impl_trait_bounds; self.delayed_lints = current_delayed_lints; + let _prev_owner_data = std::mem::replace(&mut self.resolver.item, current_ast_owner); + #[cfg(debug_assertions)] + self.resolver.general.owners.insert(owner, _prev_owner_data); + debug_assert!(!self.children.iter().any(|(id, _)| id == &owner_id.def_id)); self.children.push((owner_id.def_id, hir::MaybeOwner::Owner(info))); } diff --git a/compiler/rustc_expand/src/base.rs b/compiler/rustc_expand/src/base.rs index 476be94efd9e4..516d76a4650a7 100644 --- a/compiler/rustc_expand/src/base.rs +++ b/compiler/rustc_expand/src/base.rs @@ -1182,6 +1182,13 @@ pub trait ResolverExpand { /// Mark the scope as having a compile error so that error for lookup in this scope /// should be suppressed fn mark_scope_with_compile_error(&mut self, parent_node: NodeId); + + /// Set a new owner and return the old one. Use only in the implementation + /// of `with_owner` and always call [Self::reset_owner] afterwards + fn set_owner(&mut self, id: NodeId) -> NodeId; + + /// Switch back to the original owner. + fn reset_owner(&mut self, id: NodeId); } pub trait LintStoreExpand { diff --git a/compiler/rustc_expand/src/expand.rs b/compiler/rustc_expand/src/expand.rs index 76a9a6f9d03d9..980a6d7698e80 100644 --- a/compiler/rustc_expand/src/expand.rs +++ b/compiler/rustc_expand/src/expand.rs @@ -8,9 +8,9 @@ use rustc_ast::tokenstream::TokenStream; use rustc_ast::visit::{self, AssocCtxt, Visitor, VisitorResult, try_visit, walk_list}; use rustc_ast::{ self as ast, AssocItemKind, AstNodeWrapper, AttrArgs, AttrItemKind, AttrStyle, AttrVec, - DUMMY_NODE_ID, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs, HasNodeId, Inline, - ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId, PatKind, StmtKind, - TyKind, token, + CRATE_NODE_ID, DUMMY_NODE_ID, EarlyParsedAttribute, ExprKind, ForeignItemKind, HasAttrs, + HasNodeId, Inline, ItemKind, MacStmtStyle, MetaItemInner, MetaItemKind, ModKind, NodeId, + PatKind, StmtKind, TyKind, token, }; use rustc_ast_pretty::pprust; use rustc_attr_parsing::{ @@ -2385,11 +2385,22 @@ impl<'a, 'b> InvocationCollector<'a, 'b> { }; } } + + fn with_owner(&mut self, id: NodeId, f: impl FnOnce(&mut Self) -> T) -> T { + if id == DUMMY_NODE_ID { + f(self) + } else { + let old = self.cx.resolver.set_owner(id); + let val = f(self); + self.cx.resolver.reset_owner(old); + val + } + } } impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { fn flat_map_item(&mut self, node: Box) -> SmallVec<[Box; 1]> { - self.flat_map_node(node) + self.with_owner(node.id, |this| this.flat_map_node(node)) } fn flat_map_assoc_item( @@ -2397,22 +2408,22 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { node: Box, ctxt: AssocCtxt, ) -> SmallVec<[Box; 1]> { - match ctxt { - AssocCtxt::Trait => self.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)), + self.with_owner(node.id, |this| match ctxt { + AssocCtxt::Trait => this.flat_map_node(AstNodeWrapper::new(node, TraitItemTag)), AssocCtxt::Impl { of_trait: false, .. } => { - self.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)) + this.flat_map_node(AstNodeWrapper::new(node, ImplItemTag)) } AssocCtxt::Impl { of_trait: true, .. } => { - self.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag)) + this.flat_map_node(AstNodeWrapper::new(node, TraitImplItemTag)) } - } + }) } fn flat_map_foreign_item( &mut self, node: Box, ) -> SmallVec<[Box; 1]> { - self.flat_map_node(node) + self.with_owner(node.id, |this| this.flat_map_node(node)) } fn flat_map_variant(&mut self, node: ast::Variant) -> SmallVec<[ast::Variant; 1]> { @@ -2483,7 +2494,7 @@ impl<'a, 'b> MutVisitor for InvocationCollector<'a, 'b> { } fn visit_crate(&mut self, node: &mut ast::Crate) { - self.visit_node(node) + self.with_owner(CRATE_NODE_ID, |this| this.visit_node(node)) } fn visit_ty(&mut self, node: &mut ast::Ty) { diff --git a/compiler/rustc_interface/src/passes.rs b/compiler/rustc_interface/src/passes.rs index 6838a495fd0f2..8d2eac432f4dc 100644 --- a/compiler/rustc_interface/src/passes.rs +++ b/compiler/rustc_interface/src/passes.rs @@ -210,7 +210,7 @@ fn configure_and_expand( }; let lint_store = LintStoreExpandImpl(lint_store); - let mut ecx = ExtCtxt::new(sess, cfg, resolver, Some(&lint_store)); + let mut ecx: ExtCtxt<'_> = ExtCtxt::new(sess, cfg, resolver, Some(&lint_store)); ecx.num_standard_library_imports = num_standard_library_imports; // Expand macros now! let krate = sess.time("expand_crate", || ecx.monotonic_expander().expand_crate(krate)); diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 2c7244187f4fd..10bda226c699c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -193,6 +193,19 @@ pub struct ResolverGlobalCtxt { pub stripped_cfg_items: Vec, } +#[derive(Debug)] +pub struct PerOwnerResolverData { + pub node_id_to_def_id: NodeMap, + /// The id of the owner + pub id: ast::NodeId, +} + +impl PerOwnerResolverData { + pub fn new(id: ast::NodeId) -> Self { + Self { node_id_to_def_id: Default::default(), id } + } +} + /// Resolutions that should only be used for lowering. /// This struct is meant to be consumed by lowering. #[derive(Debug)] @@ -208,9 +221,9 @@ pub struct ResolverAstLowering { /// Lifetime parameters that lowering will have to introduce. pub extra_lifetime_params_map: NodeMap>, - pub next_node_id: ast::NodeId, + pub owners: NodeMap, - pub node_id_to_def_id: NodeMap, + pub next_node_id: ast::NodeId, pub trait_map: NodeMap>, /// List functions and methods for which lifetime elision was successful. diff --git a/compiler/rustc_passes/src/lang_items.rs b/compiler/rustc_passes/src/lang_items.rs index 25aea8e9f82a0..d1f3d3e2a025e 100644 --- a/compiler/rustc_passes/src/lang_items.rs +++ b/compiler/rustc_passes/src/lang_items.rs @@ -295,7 +295,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { self.check_for_lang( target, - self.resolver.node_id_to_def_id[&i.id], + self.resolver.owners[&i.id].node_id_to_def_id[&i.id], &i.attrs, i.span, i.opt_generics(), @@ -309,7 +309,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { fn visit_variant(&mut self, variant: &'ast ast::Variant) { self.check_for_lang( Target::Variant, - self.resolver.node_id_to_def_id[&variant.id], + self.resolver.owners[&self.parent_item.unwrap().id].node_id_to_def_id[&variant.id], &variant.attrs, variant.span, None, @@ -348,7 +348,7 @@ impl<'ast, 'tcx> visit::Visitor<'ast> for LanguageItemCollector<'ast, 'tcx> { self.check_for_lang( target, - self.resolver.node_id_to_def_id[&i.id], + self.resolver.owners[&i.id].node_id_to_def_id[&i.id], &i.attrs, i.span, generics, diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index e2fea9146c798..1a254dce4416c 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -9,6 +9,7 @@ use rustc_hir::Target; use rustc_hir::def::{CtorKind, CtorOf, DefKind}; use rustc_hir::def_id::LocalDefId; use rustc_middle::span_bug; +use rustc_middle::ty::PerOwnerResolverData; use rustc_span::hygiene::LocalExpnId; use rustc_span::{Span, Symbol, sym}; use tracing::{debug, instrument}; @@ -22,8 +23,13 @@ pub(crate) fn collect_definitions( ) { let invocation_parent = resolver.invocation_parents[&expansion]; debug!("new fragment to visit with invocation_parent: {invocation_parent:?}"); + debug_assert_eq!(resolver.current_owner.id, DUMMY_NODE_ID); + resolver.current_owner = resolver.owners.remove(&invocation_parent.owner).unwrap(); let mut visitor = DefCollector { resolver, expansion, invocation_parent }; fragment.visit_with(&mut visitor); + let tables = + mem::replace(&mut resolver.current_owner, PerOwnerResolverData::new(DUMMY_NODE_ID)); + assert!(resolver.owners.insert(invocation_parent.owner, tables).is_none()); } /// Creates `DefId`s for nodes in the AST. @@ -46,7 +52,8 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { "create_def(node_id={:?}, def_kind={:?}, parent_def={:?})", node_id, def_kind, parent_def ); - self.resolver + let def_id = self + .resolver .create_def( parent_def, node_id, @@ -55,7 +62,9 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { self.expansion.to_expn_id(), span.with_parent(None), ) - .def_id() + .def_id(); + assert!(self.resolver.node_id_to_def_id.insert(node_id, def_id).is_none()); + def_id } fn with_parent(&mut self, parent_def: LocalDefId, f: F) { @@ -64,6 +73,29 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { self.invocation_parent.parent_def = orig_parent_def; } + fn with_owner(&mut self, owner: NodeId, f: F) { + debug_assert_ne!(owner, DUMMY_NODE_ID); + if owner == CRATE_NODE_ID { + // Special case: we always have an invocation parent (set in `collect_definitions`) + // of at least the crate root, even for visiting the crate root, + // which would then remove the crate root from the tables + // list twice and try to insert it twice afterwards. + debug_assert_eq!(self.resolver.current_owner.id, CRATE_NODE_ID); + return f(self); + } + // We only get here if the owner didn't exist yet. After the owner has been created, + // future invocations of `collect_definitions` will get the owner out of the `owners` + // table. + debug_assert!(!self.resolver.owners.contains_key(&owner)); + let tables = PerOwnerResolverData::new(owner); + let orig_owner = mem::replace(&mut self.resolver.current_owner, tables); + let orig_invoc_owner = mem::replace(&mut self.invocation_parent.owner, owner); + f(self); + let tables = mem::replace(&mut self.resolver.current_owner, orig_owner); + assert!(self.resolver.owners.insert(owner, tables).is_none()); + assert_eq!(mem::replace(&mut self.invocation_parent.owner, orig_invoc_owner), owner); + } + fn with_impl_trait( &mut self, impl_trait_context: ImplTraitContext, @@ -166,38 +198,43 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } ItemKind::GlobalAsm(..) => DefKind::GlobalAsm, ItemKind::Use(use_tree) => { - self.create_def(i.id, None, DefKind::Use, use_tree.span); - return visit::walk_item(self, i); + return self.with_owner(i.id, |this| { + this.create_def(i.id, None, DefKind::Use, use_tree.span); + visit::walk_item(this, i) + }); } ItemKind::MacCall(..) | ItemKind::DelegationMac(..) => { return self.visit_macro_invoc(i.id); } }; - let def_id = - self.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span); + self.with_owner(i.id, |this| { + let def_id = + this.create_def(i.id, i.kind.ident().map(|ident| ident.name), def_kind, i.span); - if let Some(macro_data) = opt_macro_data { - self.resolver.new_local_macro(def_id, macro_data); - } + if let Some(macro_data) = opt_macro_data { + this.resolver.new_local_macro(def_id, macro_data); + } - self.with_parent(def_id, |this| { - this.with_impl_trait(ImplTraitContext::Existential, |this| { - match i.kind { - ItemKind::Struct(_, _, ref struct_def) - | ItemKind::Union(_, _, ref struct_def) => { - // If this is a unit or tuple-like struct, register the constructor. - if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) { - this.create_def( - ctor_node_id, - None, - DefKind::Ctor(CtorOf::Struct, ctor_kind), - i.span, - ); + this.with_parent(def_id, |this| { + this.with_impl_trait(ImplTraitContext::Existential, |this| { + match i.kind { + ItemKind::Struct(_, _, ref struct_def) + | ItemKind::Union(_, _, ref struct_def) => { + // If this is a unit or tuple-like struct, register the constructor. + if let Some((ctor_kind, ctor_node_id)) = CtorKind::from_ast(struct_def) + { + this.create_def( + ctor_node_id, + None, + DefKind::Ctor(CtorOf::Struct, ctor_kind), + i.span, + ); + } } + _ => {} } - _ => {} - } - visit::walk_item(this, i); + visit::walk_item(this, i); + }) }) }); } @@ -254,8 +291,10 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } fn visit_nested_use_tree(&mut self, use_tree: &'a UseTree, id: NodeId) { - self.create_def(id, None, DefKind::Use, use_tree.span); - visit::walk_use_tree(self, use_tree); + self.with_owner(id, |this| { + this.create_def(id, None, DefKind::Use, use_tree.span); + visit::walk_use_tree(this, use_tree); + }) } fn visit_foreign_item(&mut self, fi: &'a ForeignItem) { @@ -280,9 +319,11 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { ForeignItemKind::MacCall(_) => return self.visit_macro_invoc(fi.id), }; - let def = self.create_def(fi.id, Some(ident.name), def_kind, fi.span); + self.with_owner(fi.id, |this| { + let def = this.create_def(fi.id, Some(ident.name), def_kind, fi.span); - self.with_parent(def, |this| visit::walk_item(this, fi)); + this.with_parent(def, |this| visit::walk_item(this, fi)); + }) } fn visit_variant(&mut self, v: &'a Variant) { @@ -354,8 +395,10 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { } }; - let def = self.create_def(i.id, Some(ident.name), def_kind, i.span); - self.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); + self.with_owner(i.id, |this| { + let def = this.create_def(i.id, Some(ident.name), def_kind, i.span); + this.with_parent(def, |this| visit::walk_assoc_item(this, i, ctxt)); + }) } fn visit_pat(&mut self, pat: &'a Pat) { @@ -525,7 +568,7 @@ impl<'a, 'ra, 'tcx> visit::Visitor<'a> for DefCollector<'a, 'ra, 'tcx> { if krate.is_placeholder { self.visit_macro_invoc(krate.id) } else { - visit::walk_crate(self, krate) + self.with_owner(CRATE_NODE_ID, |this| visit::walk_crate(this, krate)) } } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 84aeb50abd96f..8d9ab2d320245 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -803,7 +803,10 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc let prev = replace(&mut self.diag_metadata.current_item, Some(item)); // Always report errors in items we just entered. let old_ignore = replace(&mut self.in_func_body, false); - self.with_lifetime_rib(LifetimeRibKind::Item, |this| this.resolve_item(item)); + debug!("{item:#?}"); + self.with_owner(item.id, |this| { + this.with_lifetime_rib(LifetimeRibKind::Item, |this| this.resolve_item(item)) + }); self.in_func_body = old_ignore; self.diag_metadata.current_item = prev; } @@ -1693,6 +1696,28 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { }) } + #[instrument(level = "debug", skip(self, work))] + fn with_owner(&mut self, owner: NodeId, work: impl FnOnce(&mut Self) -> T) -> T { + let old_owner = std::mem::replace( + &mut self.r.current_owner, + self.r.owners.remove(&owner).unwrap_or_else(|| { + panic!( + "unknown owner {owner}: {:?}", + self.r + .owners + .items() + .filter(|o| o.1.node_id_to_def_id.contains_key(&owner)) + .get_only() + .map(|(_, o)| o.node_id_to_def_id[&owner]) + ) + }), + ); + let ret = work(self); + let prev = std::mem::replace(&mut self.r.current_owner, old_owner); + self.r.owners.insert(prev.id, prev); + ret + } + #[instrument(level = "debug", skip(self, work))] fn with_lifetime_rib( &mut self, @@ -3255,7 +3280,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { replace(&mut self.diag_metadata.current_trait_assoc_items, Some(trait_items)); for item in trait_items { - self.resolve_trait_item(item); + self.with_owner(item.id, |this| { + this.resolve_trait_item(item); + }) } self.diag_metadata.current_trait_assoc_items = trait_assoc_items; @@ -3465,7 +3492,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { debug!("resolve_implementation with_self_rib_ns(ValueNS, ...)"); let mut seen_trait_items = Default::default(); for item in impl_items { - this.resolve_impl_item(&**item, &mut seen_trait_items, trait_id, of_trait.is_some()); + this.with_owner(item.id, |this| { + this.resolve_impl_item(&**item, &mut seen_trait_items, trait_id, of_trait.is_some()); + }) } }); }); @@ -5578,18 +5607,21 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { impl<'ra, 'tcx> Resolver<'ra, 'tcx> { pub(crate) fn late_resolve_crate(&mut self, krate: &Crate) { - visit::walk_crate(&mut ItemInfoCollector { r: self }, krate); - let mut late_resolution_visitor = LateResolutionVisitor::new(self); - late_resolution_visitor.resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID)); - visit::walk_crate(&mut late_resolution_visitor, krate); - for (id, span) in late_resolution_visitor.diag_metadata.unused_labels.iter() { - self.lint_buffer.buffer_lint( - lint::builtin::UNUSED_LABELS, - *id, - *span, - errors::UnusedLabel, - ); - } + self.with_owner(CRATE_NODE_ID, |this| { + visit::walk_crate(&mut ItemInfoCollector { r: this }, krate); + let mut late_resolution_visitor = LateResolutionVisitor::new(this); + late_resolution_visitor + .resolve_doc_links(&krate.attrs, MaybeExported::Ok(CRATE_NODE_ID)); + visit::walk_crate(&mut late_resolution_visitor, krate); + for (id, span) in late_resolution_visitor.diag_metadata.unused_labels.iter() { + this.lint_buffer.buffer_lint( + lint::builtin::UNUSED_LABELS, + *id, + *span, + errors::UnusedLabel, + ); + } + }) } } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 66f1d6b4ad55b..898b07152ec95 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -42,8 +42,8 @@ use macros::{MacroRulesDecl, MacroRulesScope, MacroRulesScopeRef}; use rustc_arena::{DroplessArena, TypedArena}; use rustc_ast::node_id::NodeMap; use rustc_ast::{ - self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, Expr, ExprKind, GenericArg, GenericArgs, - NodeId, Path, attr, + self as ast, AngleBracketedArg, CRATE_NODE_ID, Crate, DUMMY_NODE_ID, Expr, ExprKind, + GenericArg, GenericArgs, NodeId, Path, attr, }; use rustc_data_structures::fx::{FxHashMap, FxHashSet, FxIndexMap, FxIndexSet, default}; use rustc_data_structures::intern::Interned; @@ -68,15 +68,15 @@ use rustc_middle::metadata::{AmbigModChild, ModChild, Reexport}; use rustc_middle::middle::privacy::EffectiveVisibilities; use rustc_middle::query::Providers; use rustc_middle::ty::{ - self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, RegisteredTools, - ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, + self, DelegationFnSig, DelegationInfo, Feed, MainDefinition, PerOwnerResolverData, + RegisteredTools, ResolverAstLowering, ResolverGlobalCtxt, TyCtxt, TyCtxtFeed, Visibility, }; use rustc_session::config::CrateType; use rustc_session::lint::builtin::PRIVATE_MACRO_USE; use rustc_span::hygiene::{ExpnId, LocalExpnId, MacroKind, SyntaxContext, Transparency}; use rustc_span::{DUMMY_SP, Ident, Span, Symbol, kw, sym}; use smallvec::{SmallVec, smallvec}; -use tracing::debug; +use tracing::{debug, instrument}; type Res = def::Res; @@ -190,6 +190,7 @@ struct InvocationParent { impl_trait_context: ImplTraitContext, in_attr: bool, const_arg_context: ConstArgContext, + owner: NodeId, } impl InvocationParent { @@ -198,6 +199,7 @@ impl InvocationParent { impl_trait_context: ImplTraitContext::Existential, in_attr: false, const_arg_context: ConstArgContext::NonDirect, + owner: CRATE_NODE_ID, }; } @@ -1202,6 +1204,12 @@ pub struct Resolver<'ra, 'tcx> { // Used for suggestions during error reporting. pat_span_map: NodeMap = Default::default(), + /// Preserves per owner data once the owner is finished resolving. + owners: NodeMap, + + /// An entry of `owners` that gets taken out and reinserted whenever an owner is handled. + current_owner: PerOwnerResolverData, + /// Resolutions for nodes that have a single resolution. partial_res_map: NodeMap = Default::default(), /// Resolutions for import nodes, which have multiple resolutions in different namespaces. @@ -1331,7 +1339,7 @@ pub struct Resolver<'ra, 'tcx> { next_node_id: NodeId = CRATE_NODE_ID, - node_id_to_def_id: NodeMap>, + feed_for_node_id: NodeMap>, disambiguator: DisambiguatorState = DisambiguatorState::new(), @@ -1391,6 +1399,22 @@ pub struct Resolver<'ra, 'tcx> { impl_trait_names: FxHashMap = default::fx_hash_map(), } +impl<'ra, 'tcx> std::ops::DerefMut for Resolver<'ra, 'tcx> { + fn deref_mut(&mut self) -> &mut Self::Target { + assert_ne!(self.current_owner.id, DUMMY_NODE_ID); + &mut self.current_owner + } +} + +impl<'ra, 'tcx> std::ops::Deref for Resolver<'ra, 'tcx> { + type Target = PerOwnerResolverData; + + fn deref(&self) -> &Self::Target { + assert_ne!(self.current_owner.id, DUMMY_NODE_ID); + &self.current_owner + } +} + /// This provides memory for the rest of the crate. The `'ra` lifetime that is /// used by many types in this crate is an abbreviation of `ResolverArenas`. #[derive(Default)] @@ -1501,7 +1525,7 @@ impl<'tcx> Resolver<'_, 'tcx> { } fn opt_feed(&self, node: NodeId) -> Option> { - self.node_id_to_def_id.get(&node).copied() + self.feed_for_node_id.get(&node).copied() } fn feed(&self, node: NodeId) -> Feed<'tcx, LocalDefId> { @@ -1523,12 +1547,12 @@ impl<'tcx> Resolver<'_, 'tcx> { span: Span, ) -> TyCtxtFeed<'tcx, LocalDefId> { assert!( - !self.node_id_to_def_id.contains_key(&node_id), + !self.feed_for_node_id.contains_key(&node_id), "adding a def for node-id {:?}, name {:?}, data {:?} but a previous def exists: {:?}", node_id, name, def_kind, - self.tcx.definitions_untracked().def_key(self.node_id_to_def_id[&node_id].key()), + self.tcx.definitions_untracked().def_key(self.feed_for_node_id[&node_id].key()), ); // FIXME: remove `def_span` body, pass in the right spans here and call `tcx.at().create_def()` @@ -1550,7 +1574,7 @@ impl<'tcx> Resolver<'_, 'tcx> { // we don't need a mapping from `NodeId` to `LocalDefId`. if node_id != ast::DUMMY_NODE_ID { debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id); - self.node_id_to_def_id.insert(node_id, feed.downgrade()); + self.feed_for_node_id.insert(node_id, feed.downgrade()); } feed @@ -1595,11 +1619,11 @@ impl<'tcx> Resolver<'_, 'tcx> { } /// This function is very slow, as it iterates over the entire - /// [Resolver::node_id_to_def_id] map just to find the [NodeId] + /// [Resolver::feed_for_node_id] map just to find the [NodeId] /// that corresponds to the given [LocalDefId]. Only use this in /// diagnostics code paths. fn def_id_to_node_id(&self, def_id: LocalDefId) -> NodeId { - self.node_id_to_def_id + self.feed_for_node_id .items() .filter(|(_, v)| v.key() == def_id) .map(|(k, _)| *k) @@ -1634,12 +1658,16 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { true, ); - let mut node_id_to_def_id = NodeMap::default(); + let mut feed_for_node_id = NodeMap::default(); + let mut owner_data = PerOwnerResolverData::new(CRATE_NODE_ID); let crate_feed = tcx.create_local_crate_def_id(crate_span); crate_feed.def_kind(DefKind::Mod); let crate_feed = crate_feed.downgrade(); - node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed); + owner_data.node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed.key()); + let mut owners = NodeMap::default(); + owners.insert(CRATE_NODE_ID, owner_data); + feed_for_node_id.insert(CRATE_NODE_ID, crate_feed); let mut invocation_parents = FxHashMap::default(); invocation_parents.insert(LocalExpnId::ROOT, InvocationParent::ROOT); @@ -1731,7 +1759,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { single_segment_macro_resolutions: Default::default(), multi_segment_macro_resolutions: Default::default(), lint_buffer: LintBuffer::default(), - node_id_to_def_id, + feed_for_node_id, invocation_parents, trait_impls: Default::default(), confused_type_with_std_module: Default::default(), @@ -1740,6 +1768,8 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { doc_link_resolutions: Default::default(), doc_link_traits_in_scope: Default::default(), current_crate_outer_attr_insert_span, + owners, + current_owner: PerOwnerResolverData::new(DUMMY_NODE_ID), .. }; @@ -1827,8 +1857,12 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .stripped_cfg_items .into_iter() .filter_map(|item| { - let parent_module = - self.node_id_to_def_id.get(&item.parent_module)?.key().to_def_id(); + let parent_module = self + .owners + .get(&item.parent_module)? + .node_id_to_def_id + .get(&item.parent_module)? + .to_def_id(); Some(StrippedCfgItem { parent_module, ident: item.ident, cfg: item.cfg }) }) .collect(); @@ -1852,17 +1886,13 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { stripped_cfg_items, }; let ast_lowering = ty::ResolverAstLowering { + owners: self.owners, partial_res_map: self.partial_res_map, import_res_map: self.import_res_map, label_res_map: self.label_res_map, lifetimes_res_map: self.lifetimes_res_map, extra_lifetime_params_map: self.extra_lifetime_params_map, next_node_id: self.next_node_id, - node_id_to_def_id: self - .node_id_to_def_id - .into_items() - .map(|(k, f)| (k, f.key())) - .collect(), trait_map: self.trait_map, lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), @@ -2510,6 +2540,19 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { } self.main_def = Some(MainDefinition { res, is_import, span }); } + + #[instrument(level = "debug", skip(self, work))] + fn with_owner(&mut self, owner: NodeId, work: impl FnOnce(&mut Self) -> T) -> T { + let old_owner = + std::mem::replace(&mut self.current_owner, self.owners.remove(&owner).unwrap()); + let ret = work(self); + assert!( + self.owners + .insert(owner, std::mem::replace(&mut self.current_owner, old_owner)) + .is_none() + ); + ret + } } fn names_to_string(names: impl Iterator) -> String { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 99cd485241546..4a3d6e84cd422 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -4,7 +4,7 @@ use std::mem; use std::sync::Arc; -use rustc_ast::{self as ast, Crate, NodeId, attr}; +use rustc_ast::{self as ast, Crate, DUMMY_NODE_ID, NodeId, attr}; use rustc_ast_pretty::pprust; use rustc_errors::{Applicability, DiagCtxtHandle, StashKey}; use rustc_expand::base::{ @@ -20,7 +20,7 @@ use rustc_hir::attrs::{CfgEntry, StrippedCfgItem}; use rustc_hir::def::{self, DefKind, MacroKinds, Namespace, NonMacroAttrKind}; use rustc_hir::def_id::{CrateNum, DefId, LocalDefId}; use rustc_middle::middle::stability; -use rustc_middle::ty::{RegisteredTools, TyCtxt}; +use rustc_middle::ty::{PerOwnerResolverData, RegisteredTools, TyCtxt}; use rustc_session::lint::builtin::{ LEGACY_DERIVE_HELPERS, OUT_OF_SCOPE_MACRO_CALLS, UNKNOWN_DIAGNOSTIC_ATTRIBUTES, UNUSED_MACRO_RULES, UNUSED_MACROS, @@ -558,6 +558,32 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { fn insert_impl_trait_name(&mut self, id: NodeId, name: Symbol) { self.impl_trait_names.insert(id, name); } + + fn set_owner(&mut self, id: NodeId) -> NodeId { + assert_ne!(id, DUMMY_NODE_ID); + let old = std::mem::replace(&mut self.current_owner, self.owners.remove(&id).unwrap()); + let old_id = old.id; + if old.id == DUMMY_NODE_ID { + if cfg!(debug_assertions) { + let PerOwnerResolverData { node_id_to_def_id, id: _ } = old; + assert!(node_id_to_def_id.is_empty()); + } + } else { + assert!(self.owners.insert(old.id, old).is_none()); + } + old_id + } + + fn reset_owner(&mut self, id: NodeId) { + let new = if id == DUMMY_NODE_ID { + PerOwnerResolverData::new(DUMMY_NODE_ID) + } else { + self.owners.remove(&id).unwrap() + }; + let old = std::mem::replace(&mut self.current_owner, new); + assert_ne!(old.id, DUMMY_NODE_ID); + assert!(self.owners.insert(old.id, old).is_none()); + } } impl<'ra, 'tcx> Resolver<'ra, 'tcx> { From c911dddd9d6f9e4e4b65a42c8585d97084e5742d Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 17 Feb 2026 21:32:28 +0000 Subject: [PATCH 5/8] Abstract away the replacing/reinserting of the current owner --- compiler/rustc_resolve/src/def_collector.rs | 9 +++---- compiler/rustc_resolve/src/late.rs | 18 ++----------- compiler/rustc_resolve/src/lib.rs | 29 ++++++++++++++++----- compiler/rustc_resolve/src/macros.rs | 9 +++---- 4 files changed, 31 insertions(+), 34 deletions(-) diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 1a254dce4416c..0c34f843ec817 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -24,12 +24,10 @@ pub(crate) fn collect_definitions( let invocation_parent = resolver.invocation_parents[&expansion]; debug!("new fragment to visit with invocation_parent: {invocation_parent:?}"); debug_assert_eq!(resolver.current_owner.id, DUMMY_NODE_ID); - resolver.current_owner = resolver.owners.remove(&invocation_parent.owner).unwrap(); + let prev = resolver.replace_current_owner(invocation_parent.owner); let mut visitor = DefCollector { resolver, expansion, invocation_parent }; fragment.visit_with(&mut visitor); - let tables = - mem::replace(&mut resolver.current_owner, PerOwnerResolverData::new(DUMMY_NODE_ID)); - assert!(resolver.owners.insert(invocation_parent.owner, tables).is_none()); + resolver.reinsert_prev_owner(prev); } /// Creates `DefId`s for nodes in the AST. @@ -91,8 +89,7 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { let orig_owner = mem::replace(&mut self.resolver.current_owner, tables); let orig_invoc_owner = mem::replace(&mut self.invocation_parent.owner, owner); f(self); - let tables = mem::replace(&mut self.resolver.current_owner, orig_owner); - assert!(self.resolver.owners.insert(owner, tables).is_none()); + self.resolver.reinsert_prev_owner(orig_owner); assert_eq!(mem::replace(&mut self.invocation_parent.owner, orig_invoc_owner), owner); } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 8d9ab2d320245..dc95bca2bfc64 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -1698,23 +1698,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { #[instrument(level = "debug", skip(self, work))] fn with_owner(&mut self, owner: NodeId, work: impl FnOnce(&mut Self) -> T) -> T { - let old_owner = std::mem::replace( - &mut self.r.current_owner, - self.r.owners.remove(&owner).unwrap_or_else(|| { - panic!( - "unknown owner {owner}: {:?}", - self.r - .owners - .items() - .filter(|o| o.1.node_id_to_def_id.contains_key(&owner)) - .get_only() - .map(|(_, o)| o.node_id_to_def_id[&owner]) - ) - }), - ); + let old_owner = self.r.replace_current_owner(owner); let ret = work(self); - let prev = std::mem::replace(&mut self.r.current_owner, old_owner); - self.r.owners.insert(prev.id, prev); + self.r.reinsert_prev_owner(old_owner); ret } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 898b07152ec95..cf4f30e2b12d2 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1536,6 +1536,26 @@ impl<'tcx> Resolver<'_, 'tcx> { self.tcx.def_kind(self.local_def_id(node)) } + /// Get a new owner out of the owners table and set it as the current owner. + /// Returns the previous owner to be stored on the stack and reinserted with [Self::reinsert_prev_owner] + fn replace_current_owner(&mut self, owner: NodeId) -> PerOwnerResolverData { + assert_ne!(owner, DUMMY_NODE_ID); + std::mem::replace(&mut self.current_owner, self.owners.remove(&owner).unwrap()) + } + + /// Reinsert an owner previously removed and assert the same owner has not been created in the mean time. + fn reinsert_prev_owner(&mut self, prev_owner: PerOwnerResolverData) { + assert_ne!(self.current_owner.id, DUMMY_NODE_ID); + assert!( + self.owners + .insert( + self.current_owner.id, + std::mem::replace(&mut self.current_owner, prev_owner) + ) + .is_none() + ) + } + /// Adds a definition with a parent definition. fn create_def( &mut self, @@ -2543,14 +2563,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { #[instrument(level = "debug", skip(self, work))] fn with_owner(&mut self, owner: NodeId, work: impl FnOnce(&mut Self) -> T) -> T { - let old_owner = - std::mem::replace(&mut self.current_owner, self.owners.remove(&owner).unwrap()); + let old_owner = self.replace_current_owner(owner); let ret = work(self); - assert!( - self.owners - .insert(owner, std::mem::replace(&mut self.current_owner, old_owner)) - .is_none() - ); + self.reinsert_prev_owner(old_owner); ret } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 4a3d6e84cd422..65f7de535e776 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -561,7 +561,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { fn set_owner(&mut self, id: NodeId) -> NodeId { assert_ne!(id, DUMMY_NODE_ID); - let old = std::mem::replace(&mut self.current_owner, self.owners.remove(&id).unwrap()); + let old = self.replace_current_owner(id); let old_id = old.id; if old.id == DUMMY_NODE_ID { if cfg!(debug_assertions) { @@ -575,12 +575,11 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn reset_owner(&mut self, id: NodeId) { - let new = if id == DUMMY_NODE_ID { - PerOwnerResolverData::new(DUMMY_NODE_ID) + let old = if id == DUMMY_NODE_ID { + std::mem::replace(&mut self.current_owner, PerOwnerResolverData::new(DUMMY_NODE_ID)) } else { - self.owners.remove(&id).unwrap() + self.replace_current_owner(id) }; - let old = std::mem::replace(&mut self.current_owner, new); assert_ne!(old.id, DUMMY_NODE_ID); assert!(self.owners.insert(old.id, old).is_none()); } From 6c889b4cd900b24441365ef4e5d77608eae9f664 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 17 Feb 2026 21:19:15 +0000 Subject: [PATCH 6/8] Keep the owner `DefId` around even while the tables have been taken out for modification This is needed for follow-up cleanups as diagnostics still need access to the `NodeId` -> `DefId` map, but only for owners --- compiler/rustc_resolve/src/def_collector.rs | 13 ++++++-- compiler/rustc_resolve/src/lib.rs | 33 ++++++++++++++++----- compiler/rustc_resolve/src/macros.rs | 4 +-- 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_resolve/src/def_collector.rs b/compiler/rustc_resolve/src/def_collector.rs index 0c34f843ec817..ad433a6bfea4e 100644 --- a/compiler/rustc_resolve/src/def_collector.rs +++ b/compiler/rustc_resolve/src/def_collector.rs @@ -14,7 +14,7 @@ use rustc_span::hygiene::LocalExpnId; use rustc_span::{Span, Symbol, sym}; use tracing::{debug, instrument}; -use crate::{ConstArgContext, ImplTraitContext, InvocationParent, Resolver}; +use crate::{ConstArgContext, ImplTraitContext, InvocationParent, Owner, Resolver}; pub(crate) fn collect_definitions( resolver: &mut Resolver<'_, '_>, @@ -89,7 +89,16 @@ impl<'a, 'ra, 'tcx> DefCollector<'a, 'ra, 'tcx> { let orig_owner = mem::replace(&mut self.resolver.current_owner, tables); let orig_invoc_owner = mem::replace(&mut self.invocation_parent.owner, owner); f(self); - self.resolver.reinsert_prev_owner(orig_owner); + let tables = mem::replace(&mut self.resolver.current_owner, orig_owner); + assert!( + self.resolver + .owners + .insert( + owner, + Owner { def_id: tables.node_id_to_def_id[&owner], resolver_data: Some(tables) } + ) + .is_none() + ); assert_eq!(mem::replace(&mut self.invocation_parent.owner, orig_invoc_owner), owner); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index cf4f30e2b12d2..73d42c595d44d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1169,6 +1169,14 @@ pub struct ResolverOutputs { pub ast_lowering: ResolverAstLowering, } +pub struct Owner { + /// Is `None` while the owner is being processed. + resolver_data: Option, + // TODO + #[expect(dead_code)] + def_id: LocalDefId, +} + /// The main resolver class. /// /// This is the visitor that walks the whole crate. @@ -1205,7 +1213,7 @@ pub struct Resolver<'ra, 'tcx> { pat_span_map: NodeMap = Default::default(), /// Preserves per owner data once the owner is finished resolving. - owners: NodeMap, + owners: NodeMap, /// An entry of `owners` that gets taken out and reinserted whenever an owner is handled. current_owner: PerOwnerResolverData, @@ -1540,7 +1548,10 @@ impl<'tcx> Resolver<'_, 'tcx> { /// Returns the previous owner to be stored on the stack and reinserted with [Self::reinsert_prev_owner] fn replace_current_owner(&mut self, owner: NodeId) -> PerOwnerResolverData { assert_ne!(owner, DUMMY_NODE_ID); - std::mem::replace(&mut self.current_owner, self.owners.remove(&owner).unwrap()) + std::mem::replace( + &mut self.current_owner, + self.owners.get_mut(&owner).unwrap().resolver_data.take().unwrap(), + ) } /// Reinsert an owner previously removed and assert the same owner has not been created in the mean time. @@ -1548,10 +1559,10 @@ impl<'tcx> Resolver<'_, 'tcx> { assert_ne!(self.current_owner.id, DUMMY_NODE_ID); assert!( self.owners - .insert( - self.current_owner.id, - std::mem::replace(&mut self.current_owner, prev_owner) - ) + .get_mut(&self.current_owner.id) + .unwrap() + .resolver_data + .replace(std::mem::replace(&mut self.current_owner, prev_owner)) .is_none() ) } @@ -1686,7 +1697,10 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let crate_feed = crate_feed.downgrade(); owner_data.node_id_to_def_id.insert(CRATE_NODE_ID, crate_feed.key()); let mut owners = NodeMap::default(); - owners.insert(CRATE_NODE_ID, owner_data); + owners.insert( + CRATE_NODE_ID, + Owner { resolver_data: Some(owner_data), def_id: crate_feed.key() }, + ); feed_for_node_id.insert(CRATE_NODE_ID, crate_feed); let mut invocation_parents = FxHashMap::default(); @@ -1880,6 +1894,9 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let parent_module = self .owners .get(&item.parent_module)? + .resolver_data + .as_ref() + .unwrap() .node_id_to_def_id .get(&item.parent_module)? .to_def_id(); @@ -1906,7 +1923,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { stripped_cfg_items, }; let ast_lowering = ty::ResolverAstLowering { - owners: self.owners, + owners: self.owners.into_items().map(|(k, v)| (k, v.resolver_data.unwrap())).collect(), partial_res_map: self.partial_res_map, import_res_map: self.import_res_map, label_res_map: self.label_res_map, diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 65f7de535e776..03690bd9212a5 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -569,7 +569,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { assert!(node_id_to_def_id.is_empty()); } } else { - assert!(self.owners.insert(old.id, old).is_none()); + assert!(self.owners.get_mut(&old.id).unwrap().resolver_data.replace(old).is_none()); } old_id } @@ -581,7 +581,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { self.replace_current_owner(id) }; assert_ne!(old.id, DUMMY_NODE_ID); - assert!(self.owners.insert(old.id, old).is_none()); + assert!(self.owners.get_mut(&old.id).unwrap().resolver_data.replace(old).is_none()); } } From 76d50400dd89c7d5fb6d6eb14095d9d3c2d0540f Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Tue, 17 Feb 2026 11:57:28 +0000 Subject: [PATCH 7/8] Eliminate `opt_local_def_id` It was only used for accessing owners anyway, so we can just look at the new owner table directly --- compiler/rustc_resolve/src/diagnostics.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 12 +----------- compiler/rustc_resolve/src/macros.rs | 2 +- 3 files changed, 3 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_resolve/src/diagnostics.rs b/compiler/rustc_resolve/src/diagnostics.rs index 179aa58ec10a3..4f86efb2e203f 100644 --- a/compiler/rustc_resolve/src/diagnostics.rs +++ b/compiler/rustc_resolve/src/diagnostics.rs @@ -3075,7 +3075,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { .stripped_cfg_items .iter() .filter_map(|item| { - let parent_module = self.opt_local_def_id(item.parent_module)?.to_def_id(); + let parent_module = self.owners[&item.parent_module].def_id.to_def_id(); Some(StrippedCfgItem { parent_module, ident: item.ident, diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 73d42c595d44d..b208dcc4d2320 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1172,8 +1172,6 @@ pub struct ResolverOutputs { pub struct Owner { /// Is `None` while the owner is being processed. resolver_data: Option, - // TODO - #[expect(dead_code)] def_id: LocalDefId, } @@ -1524,20 +1522,12 @@ impl<'ra, 'tcx> AsRef> for Resolver<'ra, 'tcx> { } impl<'tcx> Resolver<'_, 'tcx> { - fn opt_local_def_id(&self, node: NodeId) -> Option { - self.opt_feed(node).map(|f| f.key()) - } - fn local_def_id(&self, node: NodeId) -> LocalDefId { self.feed(node).key() } - fn opt_feed(&self, node: NodeId) -> Option> { - self.feed_for_node_id.get(&node).copied() - } - fn feed(&self, node: NodeId) -> Feed<'tcx, LocalDefId> { - self.opt_feed(node).unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) + self.feed_for_node_id.get(&node).copied().unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) } fn local_def_kind(&self, node: NodeId) -> DefKind { diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index 03690bd9212a5..be867f38c62bf 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -169,7 +169,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn mark_scope_with_compile_error(&mut self, id: NodeId) { - if let Some(id) = self.opt_local_def_id(id) + if let Some(id) = self.owners.get(&id).map(|o| o.def_id) && self.tcx.def_kind(id).is_module_like() { self.mods_with_parse_errors.insert(id.to_def_id()); From face2295198ec06e31bfe0635149c0070381490b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 18 Feb 2026 08:39:42 +0000 Subject: [PATCH 8/8] Load `DefId`s from the per owner table --- compiler/rustc_resolve/src/check_unused.rs | 10 +-- .../src/effective_visibilities.rs | 19 ++-- compiler/rustc_resolve/src/imports.rs | 12 +-- compiler/rustc_resolve/src/late.rs | 86 ++++++++++--------- .../rustc_resolve/src/late/diagnostics.rs | 4 +- compiler/rustc_resolve/src/lib.rs | 16 ++-- compiler/rustc_resolve/src/macros.rs | 6 +- 7 files changed, 80 insertions(+), 73 deletions(-) diff --git a/compiler/rustc_resolve/src/check_unused.rs b/compiler/rustc_resolve/src/check_unused.rs index 45fdea82d47bc..e4eb8838d453c 100644 --- a/compiler/rustc_resolve/src/check_unused.rs +++ b/compiler/rustc_resolve/src/check_unused.rs @@ -82,7 +82,7 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> { // used now. If an import is not used at all, we signal a lint error. fn check_import(&mut self, id: ast::NodeId) { let used = self.r.used_imports.contains(&id); - let def_id = self.r.local_def_id(id); + let def_id = self.r.owners[&id].def_id; if !used { if self.r.maybe_unused_trait_imports.contains(&def_id) { // Check later. @@ -101,7 +101,7 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> { } fn check_use_tree(&mut self, use_tree: &'a ast::UseTree, id: ast::NodeId) { - if self.r.effective_visibilities.is_exported(self.r.local_def_id(id)) { + if self.r.effective_visibilities.is_exported(self.r.owners[&id].def_id) { self.check_import_as_underscore(use_tree, id); return; } @@ -211,7 +211,7 @@ impl<'a, 'ra, 'tcx> UnusedImportCheckVisitor<'a, 'ra, 'tcx> { let module = self .r - .get_nearest_non_block_module(self.r.local_def_id(extern_crate.id).to_def_id()); + .get_nearest_non_block_module(self.r.owners[&extern_crate.id].def_id.to_def_id()); if module.no_implicit_prelude { // If the module has `no_implicit_prelude`, then we don't suggest // replacing the extern crate with a use, as it would not be @@ -416,7 +416,7 @@ impl Resolver<'_, '_> { } } ImportKind::ExternCrate { id, .. } => { - let def_id = self.local_def_id(id); + let def_id = self.owners[&id].def_id; if self.extern_crate_map.get(&def_id).is_none_or(|&cnum| { !tcx.is_compiler_builtins(cnum) && !tcx.is_panic_runtime(cnum) @@ -479,7 +479,7 @@ impl Resolver<'_, '_> { None } else { let parent_module = visitor.r.get_nearest_non_block_module( - visitor.r.local_def_id(unused.use_tree_id).to_def_id(), + visitor.r.owners[&unused.use_tree_id].def_id.to_def_id(), ); match module_to_string(parent_module) { Some(module) diff --git a/compiler/rustc_resolve/src/effective_visibilities.rs b/compiler/rustc_resolve/src/effective_visibilities.rs index 55518276a4f0f..b196552ec561e 100644 --- a/compiler/rustc_resolve/src/effective_visibilities.rs +++ b/compiler/rustc_resolve/src/effective_visibilities.rs @@ -1,7 +1,7 @@ use std::mem; use rustc_ast::visit::Visitor; -use rustc_ast::{Crate, EnumDef, ast, visit}; +use rustc_ast::{Crate, EnumDef, NodeId, ast, visit}; use rustc_data_structures::fx::FxHashSet; use rustc_hir::def_id::{CRATE_DEF_ID, LocalDefId}; use rustc_middle::middle::privacy::{EffectiveVisibilities, EffectiveVisibility, Level}; @@ -47,7 +47,7 @@ impl Resolver<'_, '_> { Visibility::Restricted( import .id() - .map(|id| self.nearest_normal_mod(self.local_def_id(id))) + .map(|id| self.nearest_normal_mod(self.owners[&id].def_id)) .unwrap_or(CRATE_DEF_ID), ) } @@ -97,7 +97,7 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { for (decl, eff_vis) in visitor.import_effective_visibilities.iter() { let DeclKind::Import { import, .. } = decl.kind else { unreachable!() }; if let Some(node_id) = import.id() { - r.effective_visibilities.update_eff_vis(r.local_def_id(node_id), eff_vis, r.tcx) + r.effective_visibilities.update_eff_vis(r.owners[&node_id].def_id, eff_vis, r.tcx) } if decl.ambiguity.get().is_some() && eff_vis.is_public_at_level(Level::Reexported) { exported_ambiguities.insert(*decl); @@ -206,11 +206,16 @@ impl<'a, 'ra, 'tcx> EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { fn update_field(&mut self, def_id: LocalDefId, parent_id: LocalDefId) { self.update_def(def_id, self.r.tcx.local_visibility(def_id), ParentId::Def(parent_id)); } + + fn child_def_id(&self, parent: NodeId, child: NodeId) -> LocalDefId { + let owner = &self.r.owners[&parent]; + owner.resolver_data.as_ref().unwrap().node_id_to_def_id[&child] + } } impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> { fn visit_item(&mut self, item: &'a ast::Item) { - let def_id = self.r.local_def_id(item.id); + let def_id = self.r.owners[&item.id].def_id; // Update effective visibilities of nested items. // If it's a mod, also make the visitor walk all of its items match item.kind { @@ -233,16 +238,16 @@ impl<'a, 'ra, 'tcx> Visitor<'a> for EffectiveVisibilitiesVisitor<'a, 'ra, 'tcx> ast::ItemKind::Enum(_, _, EnumDef { ref variants }) => { self.set_bindings_effective_visibilities(def_id); for variant in variants { - let variant_def_id = self.r.local_def_id(variant.id); + let variant_def_id = self.child_def_id(item.id, variant.id); for field in variant.data.fields() { - self.update_field(self.r.local_def_id(field.id), variant_def_id); + self.update_field(self.child_def_id(item.id, field.id), variant_def_id); } } } ast::ItemKind::Struct(_, _, ref def) | ast::ItemKind::Union(_, _, ref def) => { for field in def.fields() { - self.update_field(self.r.local_def_id(field.id), def_id); + self.update_field(self.child_def_id(item.id, field.id), def_id); } } diff --git a/compiler/rustc_resolve/src/imports.rs b/compiler/rustc_resolve/src/imports.rs index d9f9d1ff5a479..06631d1881fae 100644 --- a/compiler/rustc_resolve/src/imports.rs +++ b/compiler/rustc_resolve/src/imports.rs @@ -227,7 +227,7 @@ impl<'ra> ImportData<'ra> { } pub(crate) fn simplify(&self, r: &Resolver<'_, '_>) -> Reexport { - let to_def_id = |id| r.local_def_id(id).to_def_id(); + let to_def_id = |id| r.owners[&id].def_id.to_def_id(); match self.kind { ImportKind::Single { id, .. } => Reexport::Single(to_def_id(id)), ImportKind::Glob { id, .. } => Reexport::Glob(to_def_id(id)), @@ -737,7 +737,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { && glob_decl.res() != Res::Err && let DeclKind::Import { import: glob_import, .. } = glob_decl.kind && let Some(glob_import_id) = glob_import.id() - && let glob_import_def_id = self.local_def_id(glob_import_id) + && let glob_import_def_id = self.owners[&glob_import_id].def_id && self.effective_visibilities.is_exported(glob_import_def_id) && glob_decl.vis().is_public() && !binding.vis().is_public() @@ -766,7 +766,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let DeclKind::Import { import, .. } = binding.kind && let Some(binding_id) = import.id() - && let import_def_id = self.local_def_id(binding_id) + && let import_def_id = self.owners[&binding_id].def_id && self.effective_visibilities.is_exported(import_def_id) && let Res::Def(reexported_kind, reexported_def_id) = binding.res() && !matches!(reexported_kind, DefKind::Ctor(..)) @@ -1149,7 +1149,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if let Some(max_vis) = max_vis.get() && !max_vis.is_at_least(import.vis, self.tcx) { - let def_id = self.local_def_id(id); + let def_id = self.owners[&id].def_id; self.lint_buffer.buffer_lint( UNUSED_IMPORTS, id, @@ -1394,7 +1394,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { if !any_successful_reexport { let (ns, binding) = reexport_error.unwrap(); if let Some(extern_crate_id) = pub_use_of_private_extern_crate_hack(import, binding) { - let extern_crate_sp = self.tcx.source_span(self.local_def_id(extern_crate_id)); + let extern_crate_sp = self.tcx.source_span(self.owners[&extern_crate_id].def_id); self.lint_buffer.buffer_lint( PUB_USE_OF_PRIVATE_EXTERN_CRATE, import_id, @@ -1489,7 +1489,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { // Skip if the import is public or was used through non scope-based resolution, // e.g. through a module-relative path. if self.import_use_map.get(&import) == Some(&Used::Other) - || self.effective_visibilities.is_exported(self.local_def_id(id)) + || self.effective_visibilities.is_exported(self.owners[&id].def_id) { return false; } diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index dc95bca2bfc64..2f1553aa0e373 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -662,7 +662,7 @@ enum MaybeExported<'a> { impl MaybeExported<'_> { fn eval(self, r: &Resolver<'_, '_>) -> bool { let def_id = match self { - MaybeExported::Ok(node_id) => Some(r.local_def_id(node_id)), + MaybeExported::Ok(node_id) => Some(r.node_id_to_def_id[&node_id]), MaybeExported::Impl(Some(trait_def_id)) | MaybeExported::ImplItem(Ok(trait_def_id)) => { trait_def_id.as_local() } @@ -1015,36 +1015,38 @@ impl<'ast, 'ra, 'tcx> Visitor<'ast> for LateResolutionVisitor<'_, 'ast, 'ra, 'tc ); } fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { - self.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id)); - let def_kind = self.r.local_def_kind(foreign_item.id); - match foreign_item.kind { - ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => { - self.with_generic_param_rib( - &generics.params, - RibKind::Item(HasGenericParams::Yes(generics.span), def_kind), - foreign_item.id, - LifetimeBinderKind::Item, - generics.span, - |this| visit::walk_item(this, foreign_item), - ); - } - ForeignItemKind::Fn(box Fn { ref generics, .. }) => { - self.with_generic_param_rib( - &generics.params, - RibKind::Item(HasGenericParams::Yes(generics.span), def_kind), - foreign_item.id, - LifetimeBinderKind::Function, - generics.span, - |this| visit::walk_item(this, foreign_item), - ); - } - ForeignItemKind::Static(..) => { - self.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item)) - } - ForeignItemKind::MacCall(..) => { - panic!("unexpanded macro in resolve!") + self.with_owner(foreign_item.id, |this| { + this.resolve_doc_links(&foreign_item.attrs, MaybeExported::Ok(foreign_item.id)); + let def_kind = this.r.local_def_kind(foreign_item.id); + match foreign_item.kind { + ForeignItemKind::TyAlias(box TyAlias { ref generics, .. }) => { + this.with_generic_param_rib( + &generics.params, + RibKind::Item(HasGenericParams::Yes(generics.span), def_kind), + foreign_item.id, + LifetimeBinderKind::Item, + generics.span, + |this| visit::walk_item(this, foreign_item), + ); + } + ForeignItemKind::Fn(box Fn { ref generics, .. }) => { + this.with_generic_param_rib( + &generics.params, + RibKind::Item(HasGenericParams::Yes(generics.span), def_kind), + foreign_item.id, + LifetimeBinderKind::Function, + generics.span, + |this| visit::walk_item(this, foreign_item), + ); + } + ForeignItemKind::Static(..) => { + this.with_static_rib(def_kind, |this| visit::walk_item(this, foreign_item)) + } + ForeignItemKind::MacCall(..) => { + panic!("unexpanded macro in resolve!") + } } - } + }) } fn visit_fn(&mut self, fn_kind: FnKind<'ast>, _: &AttrVec, sp: Span, fn_id: NodeId) { let previous_value = self.diag_metadata.current_function; @@ -2704,7 +2706,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { LifetimeBinderKind::Item, generics.span, |this| { - let item_def_id = this.r.local_def_id(item.id).to_def_id(); + let item_def_id = this.r.owners[&item.id].def_id.to_def_id(); this.with_self_rib( Res::SelfTyAlias { alias_to: item_def_id, is_trait_impl: false }, |this| { @@ -2818,7 +2820,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { LifetimeBinderKind::Item, generics.span, |this| { - let local_def_id = this.r.local_def_id(item.id).to_def_id(); + let local_def_id = this.r.owners[&item.id].def_id.to_def_id(); this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds, BoundKind::SuperTraits); @@ -2837,7 +2839,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { LifetimeBinderKind::Item, generics.span, |this| { - let local_def_id = this.r.local_def_id(item.id).to_def_id(); + let local_def_id = this.r.owners[&item.id].def_id.to_def_id(); this.with_self_rib(Res::SelfTyParam { trait_: local_def_id }, |this| { this.visit_generics(generics); walk_list!(this, visit_param_bound, bounds, BoundKind::Bound); @@ -2847,7 +2849,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { } ItemKind::Mod(..) => { - let module = self.r.expect_module(self.r.local_def_id(item.id).to_def_id()); + let module = self.r.expect_module(self.r.owners[&item.id].def_id.to_def_id()); let orig_module = replace(&mut self.parent_scope.module, module); self.with_rib(ValueNS, RibKind::Module(module), |this| { this.with_rib(TypeNS, RibKind::Module(module), |this| { @@ -2970,7 +2972,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { // Maintain macro_rules scopes in the same way as during early resolution // for diagnostics and doc links. if macro_def.macro_rules { - let def_id = self.r.local_def_id(item.id); + let def_id = self.r.owners[&item.id].def_id; self.parent_scope.macro_rules = self.r.macro_rules_scopes[&def_id]; } @@ -3131,7 +3133,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { continue; } - let def_id = self.r.local_def_id(param.id); + let def_id = self.r.node_id_to_def_id[¶m.id]; // Plain insert (no renaming). let (rib, def_kind) = match param.kind { @@ -3446,7 +3448,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { |this, trait_id| { this.resolve_doc_links(attrs, MaybeExported::Impl(trait_id)); - let item_def_id = this.r.local_def_id(item_id); + let item_def_id = this.r.owners[&item_id].def_id; // Register the trait definitions from here. if let Some(trait_id) = trait_id { @@ -3837,7 +3839,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { self.visit_path(&delegation.path); self.r.delegation_infos.insert( - self.r.local_def_id(item_id), + self.r.owners[&item_id].def_id, DelegationInfo { attrs: create_delegation_attrs(attrs), resolution_node: if is_in_trait_impl { item_id } else { delegation.id }, @@ -4975,7 +4977,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { && let ItemKind::MacroDef(..) = item.kind { num_macro_definition_ribs += 1; - let res = self.r.local_def_id(item.id).to_def_id(); + let res = self.r.owners[&item.id].def_id.to_def_id(); self.ribs[ValueNS].push(Rib::new(RibKind::MacroDefinition(res))); self.label_ribs.push(Rib::new(RibKind::MacroDefinition(res))); } @@ -5458,7 +5460,7 @@ impl ItemInfoCollector<'_, '_, '_> { attrs: &[Attribute], ) { self.r.delegation_fn_sigs.insert( - self.r.local_def_id(id), + self.r.owners[&id].def_id, DelegationFnSig { header, param_count: decl.inputs.len(), @@ -5538,7 +5540,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { self.collect_fn_info(sig.header, &sig.decl, item.id, &item.attrs); } - let def_id = self.r.local_def_id(item.id); + let def_id = self.r.owners[&item.id].def_id; let count = generics .params .iter() @@ -5582,7 +5584,7 @@ impl<'ast> Visitor<'ast> for ItemInfoCollector<'_, '_, '_> { } if let AssocItemKind::Type(box ast::TyAlias { generics, .. }) = &item.kind { - let def_id = self.r.local_def_id(item.id); + let def_id = self.r.owners[&item.id].def_id; if let Some(suggestion) = required_generic_args_suggestion(generics) { self.r.item_required_generic_args_suggestions.insert(def_id, suggestion); } diff --git a/compiler/rustc_resolve/src/late/diagnostics.rs b/compiler/rustc_resolve/src/late/diagnostics.rs index 5874b192216cc..e845114eafbec 100644 --- a/compiler/rustc_resolve/src/late/diagnostics.rs +++ b/compiler/rustc_resolve/src/late/diagnostics.rs @@ -2801,7 +2801,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { if self .r .delegation_fn_sigs - .get(&self.r.local_def_id(assoc_item.id)) + .get(&self.r.node_id_to_def_id[&assoc_item.id]) .is_some_and(|sig| sig.has_self) => { AssocSuggestion::MethodWithSelf { called } @@ -3408,7 +3408,7 @@ impl<'ast, 'ra, 'tcx> LateResolutionVisitor<'_, 'ast, 'ra, 'tcx> { for (param_index, param) in params.iter().enumerate() { let GenericParamKind::Lifetime = param.kind else { continue }; - let def_id = self.r.local_def_id(param.id); + let def_id = self.r.node_id_to_def_id[¶m.id]; let use_set = self.lifetime_uses.remove(&def_id); debug!( diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index b208dcc4d2320..80946fb4df649 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1522,16 +1522,16 @@ impl<'ra, 'tcx> AsRef> for Resolver<'ra, 'tcx> { } impl<'tcx> Resolver<'_, 'tcx> { - fn local_def_id(&self, node: NodeId) -> LocalDefId { - self.feed(node).key() - } - fn feed(&self, node: NodeId) -> Feed<'tcx, LocalDefId> { - self.feed_for_node_id.get(&node).copied().unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) + self.feed_for_node_id + .get(&node) + .copied() + .unwrap_or_else(|| panic!("no entry for node id: `{node:?}`")) } + /// Obtain the `DefKind` for an owner's `NodeId`. fn local_def_kind(&self, node: NodeId) -> DefKind { - self.tcx.def_kind(self.local_def_id(node)) + self.tcx.def_kind(self.owners[&node].def_id) } /// Get a new owner out of the owners table and set it as the current owner. @@ -2104,7 +2104,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let mut import_ids = smallvec![]; while let DeclKind::Import { import, source_decl, .. } = kind { if let Some(node_id) = import.id() { - let def_id = self.local_def_id(node_id); + let def_id = self.owners[&node_id].def_id; self.maybe_unused_trait_imports.insert(def_id); import_ids.push(def_id); } @@ -2240,7 +2240,7 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { #[inline] fn add_to_glob_map(&mut self, import: Import<'_>, name: Symbol) { if let ImportKind::Glob { id, .. } = import.kind { - let def_id = self.local_def_id(id); + let def_id = self.owners[&id].def_id; self.glob_map.entry(def_id).or_default().insert(name); } } diff --git a/compiler/rustc_resolve/src/macros.rs b/compiler/rustc_resolve/src/macros.rs index be867f38c62bf..47ef6956290af 100644 --- a/compiler/rustc_resolve/src/macros.rs +++ b/compiler/rustc_resolve/src/macros.rs @@ -221,7 +221,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { parent_module_id: Option, ) -> LocalExpnId { let parent_module = - parent_module_id.map(|module_id| self.local_def_id(module_id).to_def_id()); + parent_module_id.map(|module_id| self.owners[&module_id].def_id.to_def_id()); let expn_id = self.tcx.with_stable_hashing_context(|hcx| { LocalExpnId::fresh( ExpnData::allow_unstable( @@ -363,7 +363,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { if unused_arms.is_empty() { continue; } - let def_id = self.local_def_id(node_id); + let def_id = self.owners[&node_id].def_id; let m = &self.local_macro_map[&def_id]; let SyntaxExtensionKind::MacroRules(ref m) = m.ext.kind else { continue; @@ -495,7 +495,7 @@ impl<'ra, 'tcx> ResolverExpand for Resolver<'ra, 'tcx> { } fn declare_proc_macro(&mut self, id: NodeId) { - self.proc_macros.push(self.local_def_id(id)) + self.proc_macros.push(self.owners[&id].def_id) } fn append_stripped_cfg_item(