From e83d369a29f225ec7470e616c90b9ee0d923a96b Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Fri, 29 May 2026 10:24:51 +0200 Subject: [PATCH 1/4] Use default field values to avoid some churn --- compiler/rustc_middle/src/lib.rs | 1 + compiler/rustc_middle/src/ty/mod.rs | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/compiler/rustc_middle/src/lib.rs b/compiler/rustc_middle/src/lib.rs index a9e547b5862a6..a018951a94770 100644 --- a/compiler/rustc_middle/src/lib.rs +++ b/compiler/rustc_middle/src/lib.rs @@ -37,6 +37,7 @@ #![feature(core_intrinsics)] #![feature(debug_closure_helpers)] #![feature(decl_macro)] +#![feature(default_field_values)] #![feature(deref_patterns)] #![feature(discriminant_kind)] #![feature(extern_types)] diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 28e18331d7127..9e3c9b18626e0 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -205,7 +205,7 @@ pub struct ResolverGlobalCtxt { #[derive(Debug)] pub struct PerOwnerResolverData { - pub node_id_to_def_id: NodeMap, + pub node_id_to_def_id: NodeMap = Default::default(), /// The id of the owner pub id: ast::NodeId, /// The `DefId` of the owner, can't be found in `node_id_to_def_id`. @@ -214,7 +214,7 @@ pub struct PerOwnerResolverData { impl PerOwnerResolverData { pub fn new(id: ast::NodeId, def_id: LocalDefId) -> PerOwnerResolverData { - PerOwnerResolverData { node_id_to_def_id: Default::default(), id, def_id } + PerOwnerResolverData { id, def_id, .. } } } From fec454558b4974bb237f5513ab193f9f4fcef439 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Wed, 27 May 2026 13:22:12 +0200 Subject: [PATCH 2/4] Track `lifetime_elision_allowed` per owner, and discard fn ptr and `Fn()` syntax registrations of it, they are never used --- compiler/rustc_ast_lowering/src/lib.rs | 8 +++----- compiler/rustc_middle/src/ty/mod.rs | 7 ++++--- compiler/rustc_resolve/src/late.rs | 4 +++- compiler/rustc_resolve/src/lib.rs | 3 --- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 9e855f305ae84..3cb36792bfeb7 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -321,10 +321,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { fn owner_def_id(&self, id: NodeId) -> LocalDefId { self.owners[&id].def_id } - - fn lifetime_elision_allowed(&self, id: NodeId) -> bool { - self.lifetime_elision_allowed.contains(&id) - } } /// How relaxed bounds `?Trait` should be treated. @@ -1853,7 +1849,9 @@ impl<'hir> LoweringContext<'_, 'hir> { _ => hir::ImplicitSelfKind::None, } })) - .set_lifetime_elision_allowed(self.resolver.lifetime_elision_allowed(fn_node_id)) + .set_lifetime_elision_allowed( + self.owner.id == fn_node_id && self.owner.lifetime_elision_allowed, + ) .set_c_variadic(c_variadic); self.arena.alloc(hir::FnDecl { inputs, output, fn_decl_kind }) diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 9e3c9b18626e0..d8626567aef67 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -31,7 +31,7 @@ use rustc_ast as ast; use rustc_ast::expand::typetree::{FncTree, Kind, Type, TypeTree}; use rustc_ast::node_id::NodeMap; pub use rustc_ast_ir::{Movability, Mutability, try_visit}; -use rustc_data_structures::fx::{FxHashSet, FxIndexMap, FxIndexSet}; +use rustc_data_structures::fx::{FxIndexMap, FxIndexSet}; use rustc_data_structures::intern::Interned; use rustc_data_structures::stable_hash::{StableHash, StableHashCtxt, StableHasher}; use rustc_data_structures::steal::Steal; @@ -206,6 +206,9 @@ pub struct ResolverGlobalCtxt { #[derive(Debug)] pub struct PerOwnerResolverData { pub node_id_to_def_id: NodeMap = Default::default(), + /// Whether lifetime elision was successful. + pub lifetime_elision_allowed: bool = false, + /// The id of the owner pub id: ast::NodeId, /// The `DefId` of the owner, can't be found in `node_id_to_def_id`. @@ -238,8 +241,6 @@ pub struct ResolverAstLowering<'tcx> { pub owners: NodeMap, pub trait_map: NodeMap<&'tcx [hir::TraitCandidate<'tcx>]>, - /// List functions and methods for which lifetime elision was successful. - pub lifetime_elision_allowed: FxHashSet, /// Lints that were emitted by the resolver and early lints. pub lint_buffer: Steal, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index d7ff0ebb3c993..ae6043530c919 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2434,7 +2434,9 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let outer_failures = take(&mut this.diag_metadata.current_elision_failures); let output_rib = if let Ok(res) = elision_lifetime.as_ref() { - this.r.lifetime_elision_allowed.insert(fn_id); + if fn_id == this.r.current_owner.id { + this.r.current_owner.lifetime_elision_allowed = true; + } LifetimeRibKind::Elided(*res) } else { LifetimeRibKind::ElisionFailure diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 0889a29571292..542211f060572 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1522,8 +1522,6 @@ pub struct Resolver<'ra, 'tcx> { /// they are declared in the static array generated by proc_macro_harness. proc_macros: Vec = Vec::new(), confused_type_with_std_module: FxIndexMap, - /// Whether lifetime elision was successful. - lifetime_elision_allowed: FxHashSet = default::fx_hash_set(), /// Names of items that were stripped out via cfg with their corresponding cfg meta item. stripped_cfg_items: Vec> = Vec::new(), @@ -2011,7 +2009,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { next_node_id: self.next_node_id, owners: self.owners, trait_map: self.trait_map, - lifetime_elision_allowed: self.lifetime_elision_allowed, lint_buffer: Steal::new(self.lint_buffer), delegation_infos: self.delegation_infos, disambiguators, From 5b37028e31515790b4c45056ed07a03a58018304 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 28 May 2026 10:23:14 +0200 Subject: [PATCH 3/4] Track `label_res_map` per-owner --- compiler/rustc_ast_lowering/src/expr.rs | 2 +- compiler/rustc_ast_lowering/src/lib.rs | 5 ----- compiler/rustc_middle/src/ty/mod.rs | 10 ++++++++-- compiler/rustc_resolve/src/late.rs | 2 +- compiler/rustc_resolve/src/lib.rs | 3 --- 5 files changed, 10 insertions(+), 12 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 87e1d9aa7a114..ce20aaf4e0276 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1549,7 +1549,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_loop_destination(&mut self, destination: Option<(NodeId, Label)>) -> hir::Destination { let target_id = match destination { Some((id, _)) => { - if let Some(loop_id) = self.resolver.get_label_res(id) { + if let Some(loop_id) = self.owner.get_label_res(id) { let local_id = self.ident_and_label_to_local_id[&loop_id]; let loop_hir_id = HirId { owner: self.current_hir_id_owner, local_id }; Ok(loop_hir_id) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 3cb36792bfeb7..f19a1fc95a495 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -293,11 +293,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { self.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() - } - /// Obtains resolution for a lifetime with the given `NodeId`. fn get_lifetime_res(&self, id: NodeId) -> Option { self.lifetimes_res_map.get(&id).copied() diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index d8626567aef67..300da2a0828e4 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -208,6 +208,9 @@ pub struct PerOwnerResolverData { pub node_id_to_def_id: NodeMap = Default::default(), /// Whether lifetime elision was successful. pub lifetime_elision_allowed: bool = false, + /// Resolutions for labels. + /// Maps from NodeId of the break/continue expression to the NodeId of their corresponding blocks or loops. + pub label_res_map: NodeMap = Default::default(), /// The id of the owner pub id: ast::NodeId, @@ -219,6 +222,11 @@ impl PerOwnerResolverData { pub fn new(id: ast::NodeId, def_id: LocalDefId) -> PerOwnerResolverData { PerOwnerResolverData { id, def_id, .. } } + + /// Obtains resolution for a label with the given `NodeId`. + pub fn get_label_res(&self, id: ast::NodeId) -> Option { + self.label_res_map.get(&id).copied() + } } /// Resolutions that should only be used for lowering. @@ -229,8 +237,6 @@ pub struct ResolverAstLowering<'tcx> { pub partial_res_map: NodeMap, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. pub import_res_map: NodeMap>>>, - /// Resolutions for labels (node IDs of their corresponding blocks or loops). - pub label_res_map: NodeMap, /// Resolutions for lifetimes. pub lifetimes_res_map: NodeMap, /// Lifetime parameters that lowering will have to introduce. diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index ae6043530c919..7030859916fbe 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -5199,7 +5199,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { match self.resolve_label(label.ident) { Ok((node_id, _)) => { // Since this res is a label, it is never read. - self.r.label_res_map.insert(expr.id, node_id); + self.r.current_owner.label_res_map.insert(expr.id, node_id); self.diag_metadata.unused_labels.swap_remove(&node_id); } Err(error) => { diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 542211f060572..7c80cfa878b89 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1369,8 +1369,6 @@ pub struct Resolver<'ra, 'tcx> { import_res_map: NodeMap>> = Default::default(), /// An import will be inserted into this map if it has been used. import_use_map: FxHashMap, Used> = default::fx_hash_map(), - /// Resolutions for labels (node IDs of their corresponding blocks or loops). - label_res_map: NodeMap = Default::default(), /// Resolutions for lifetimes. lifetimes_res_map: NodeMap = Default::default(), /// Lifetime parameters that lowering will have to introduce. @@ -2003,7 +2001,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let ast_lowering = ty::ResolverAstLowering { 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, From b7ea5d8ab76b32ed111b24fa4bfdbc45a8cc7bc3 Mon Sep 17 00:00:00 2001 From: Oli Scherer Date: Thu, 28 May 2026 10:34:07 +0200 Subject: [PATCH 4/4] Track `lifetimes_res_map` per owner --- compiler/rustc_ast_lowering/src/lib.rs | 22 ++++++++-------------- compiler/rustc_ast_lowering/src/path.rs | 4 ++-- compiler/rustc_middle/src/ty/mod.rs | 9 +++++++-- compiler/rustc_resolve/src/late.rs | 6 +++--- compiler/rustc_resolve/src/lib.rs | 6 +----- 5 files changed, 21 insertions(+), 26 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index f19a1fc95a495..4045f08c053ed 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -293,11 +293,6 @@ impl<'tcx> ResolverAstLowering<'tcx> { self.import_res_map.get(&id).copied().unwrap_or_default() } - /// Obtains resolution for a lifetime with the given `NodeId`. - fn get_lifetime_res(&self, id: NodeId) -> Option { - self.lifetimes_res_map.get(&id).copied() - } - /// Obtain the list of lifetimes parameters to add to an item. /// /// Extra lifetime parameters should only be added in places that can appear @@ -1603,7 +1598,7 @@ impl<'hir> LoweringContext<'_, 'hir> { None => { let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) = - self.resolver.get_lifetime_res(t.id) + self.owner.get_lifetime_res(t.id) { assert_eq!(start.plus(1), end); start @@ -2012,7 +2007,7 @@ impl<'hir> LoweringContext<'_, 'hir> { source: LifetimeSource, syntax: LifetimeSyntax, ) -> &'hir hir::Lifetime { - let res = if let Some(res) = self.resolver.get_lifetime_res(id) { + let res = if let Some(res) = self.owner.get_lifetime_res(id) { match res { LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param), LifetimeRes::Fresh { param, .. } => { @@ -2098,13 +2093,12 @@ impl<'hir> LoweringContext<'_, 'hir> { // AST resolution emitted an error on those parameters, so we lower them using // `ParamName::Error`. let ident = self.lower_ident(param.ident); - let param_name = if let Some(LifetimeRes::Error(..)) = - self.resolver.get_lifetime_res(param.id) - { - ParamName::Error(ident) - } else { - ParamName::Plain(ident) - }; + let param_name = + if let Some(LifetimeRes::Error(..)) = self.owner.get_lifetime_res(param.id) { + ParamName::Error(ident) + } else { + ParamName::Plain(ident) + }; let kind = hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }; diff --git a/compiler/rustc_ast_lowering/src/path.rs b/compiler/rustc_ast_lowering/src/path.rs index ef60dc6fc4f1c..f5a306aa9140d 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -17,7 +17,7 @@ use super::errors::{ }; use super::{ AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition, - LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, + LifetimeRes, LoweringContext, ParamMode, }; impl<'hir> LoweringContext<'_, 'hir> { @@ -422,7 +422,7 @@ impl<'hir> LoweringContext<'_, 'hir> { segment_ident_span: Span, generic_args: &mut GenericArgsCtor<'hir>, ) { - let (start, end) = match self.resolver.get_lifetime_res(segment_id) { + let (start, end) = match self.owner.get_lifetime_res(segment_id) { Some(LifetimeRes::ElidedAnchor { start, end }) => (start, end), None => return, Some(res) => { diff --git a/compiler/rustc_middle/src/ty/mod.rs b/compiler/rustc_middle/src/ty/mod.rs index 300da2a0828e4..6df1ed82d260a 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -211,6 +211,8 @@ pub struct PerOwnerResolverData { /// Resolutions for labels. /// Maps from NodeId of the break/continue expression to the NodeId of their corresponding blocks or loops. pub label_res_map: NodeMap = Default::default(), + /// Resolutions for lifetimes. + pub lifetimes_res_map: NodeMap = Default::default(), /// The id of the owner pub id: ast::NodeId, @@ -227,6 +229,11 @@ impl PerOwnerResolverData { pub fn get_label_res(&self, id: ast::NodeId) -> Option { self.label_res_map.get(&id).copied() } + + /// Obtains resolution for a lifetime with the given `NodeId`. + pub fn get_lifetime_res(&self, id: ast::NodeId) -> Option { + self.lifetimes_res_map.get(&id).copied() + } } /// Resolutions that should only be used for lowering. @@ -237,8 +244,6 @@ pub struct ResolverAstLowering<'tcx> { pub partial_res_map: NodeMap, /// Resolutions for import nodes, which have multiple resolutions in different namespaces. pub import_res_map: NodeMap>>>, - /// Resolutions for lifetimes. - pub lifetimes_res_map: NodeMap, /// Lifetime parameters that lowering will have to introduce. pub extra_lifetime_params_map: NodeMap>, diff --git a/compiler/rustc_resolve/src/late.rs b/compiler/rustc_resolve/src/late.rs index 7030859916fbe..58899ffd53ab9 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2406,7 +2406,7 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { /// Define a new lifetime (e.g. in generics) #[instrument(level = "debug", skip(self))] fn record_lifetime_def(&mut self, id: NodeId, res: LifetimeRes) { - if let Some(prev_res) = self.r.lifetimes_res_map.insert(id, res) { + if let Some(prev_res) = self.r.current_owner.lifetimes_res_map.insert(id, res) { panic!( "lifetime parameter {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)" ) @@ -2611,11 +2611,11 @@ impl<'a, 'ast, 'ra, 'tcx> LateResolutionVisitor<'a, 'ast, 'ra, 'tcx> { let lt_id = if let Some(lt) = lt { lt.id } else { - let res = self.r.lifetimes_res_map[&ty.id]; + let res = self.r.current_owner.lifetimes_res_map[&ty.id]; let LifetimeRes::ElidedAnchor { start, .. } = res else { bug!() }; start }; - let lt_res = self.r.lifetimes_res_map[<_id]; + let lt_res = self.r.current_owner.lifetimes_res_map[<_id]; trace!("FindReferenceVisitor inserting res={:?}", lt_res); self.lifetime.insert(lt_res); } diff --git a/compiler/rustc_resolve/src/lib.rs b/compiler/rustc_resolve/src/lib.rs index 7c80cfa878b89..ffb2181bae3a9 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -53,8 +53,7 @@ use rustc_feature::BUILTIN_ATTRIBUTES; use rustc_hir::attrs::StrippedCfgItem; use rustc_hir::def::Namespace::{self, *}; use rustc_hir::def::{ - self, CtorOf, DefKind, DocLinkResMap, LifetimeRes, MacroKinds, NonMacroAttrKind, PartialRes, - PerNS, + self, CtorOf, DefKind, DocLinkResMap, MacroKinds, NonMacroAttrKind, PartialRes, PerNS, }; use rustc_hir::def_id::{CRATE_DEF_ID, CrateNum, DefId, LOCAL_CRATE, LocalDefId, LocalDefIdMap}; use rustc_hir::definitions::{PerParentDisambiguatorState, PerParentDisambiguatorsMap}; @@ -1369,8 +1368,6 @@ pub struct Resolver<'ra, 'tcx> { import_res_map: NodeMap>> = Default::default(), /// An import will be inserted into this map if it has been used. import_use_map: FxHashMap, Used> = default::fx_hash_map(), - /// Resolutions for lifetimes. - lifetimes_res_map: NodeMap = Default::default(), /// Lifetime parameters that lowering will have to introduce. extra_lifetime_params_map: NodeMap> = Default::default(), @@ -2001,7 +1998,6 @@ impl<'ra, 'tcx> Resolver<'ra, 'tcx> { let ast_lowering = ty::ResolverAstLowering { partial_res_map: self.partial_res_map, import_res_map: self.import_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, owners: self.owners,