diff --git a/compiler/rustc_ast_lowering/src/expr.rs b/compiler/rustc_ast_lowering/src/expr.rs index 87e1d9aa7a11..ce20aaf4e027 100644 --- a/compiler/rustc_ast_lowering/src/expr.rs +++ b/compiler/rustc_ast_lowering/src/expr.rs @@ -1549,7 +1549,7 @@ fn lower_label( 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 a916ee1f143b..a28cb068aa4a 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -293,16 +293,6 @@ fn get_import_res(&self, id: NodeId) -> PerNS>> { 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() - } - /// Obtain the list of lifetimes parameters to add to an item. /// /// Extra lifetime parameters should only be added in places that can appear @@ -321,10 +311,6 @@ fn delegation_info(&self, id: LocalDefId) -> Option<&DelegationInfo> { 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. @@ -1625,7 +1611,7 @@ fn lower_ty_direct_lifetime( 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 @@ -1866,7 +1852,9 @@ fn lower_fn_decl( _ => 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 }) @@ -2032,7 +2020,7 @@ fn new_named_lifetime( 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, .. } => { @@ -2118,13 +2106,12 @@ fn lower_generic_param_kind( // 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 ef60dc6fc4f1..f5a306aa9140 100644 --- a/compiler/rustc_ast_lowering/src/path.rs +++ b/compiler/rustc_ast_lowering/src/path.rs @@ -17,7 +17,7 @@ }; use super::{ AllowReturnTypeNotation, GenericArgsCtor, GenericArgsMode, ImplTraitContext, ImplTraitPosition, - LifetimeRes, LoweringContext, ParamMode, ResolverAstLoweringExt, + LifetimeRes, LoweringContext, ParamMode, }; impl<'hir> LoweringContext<'_, 'hir> { @@ -422,7 +422,7 @@ fn maybe_insert_elided_lifetimes_in_path( 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/lib.rs b/compiler/rustc_middle/src/lib.rs index a9e547b5862a..a018951a9477 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 74f9e75fb48c..591b6f5cfa5c 100644 --- a/compiler/rustc_middle/src/ty/mod.rs +++ b/compiler/rustc_middle/src/ty/mod.rs @@ -31,7 +31,7 @@ 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,7 +206,15 @@ pub struct ResolverGlobalCtxt { #[derive(Debug)] pub struct PerOwnerResolverData { - pub node_id_to_def_id: NodeMap, + 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(), + /// Resolutions for lifetimes. + pub lifetimes_res_map: 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`. @@ -215,7 +223,17 @@ 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, .. } + } + + /// 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() + } + + /// 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() } } @@ -227,10 +245,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. pub extra_lifetime_params_map: NodeMap>, @@ -239,8 +253,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 fb8de90d28ac..ee08a2fbcd97 100644 --- a/compiler/rustc_resolve/src/late.rs +++ b/compiler/rustc_resolve/src/late.rs @@ -2412,7 +2412,7 @@ fn record_lifetime_res( res: LifetimeRes, candidate: LifetimeElisionCandidate, ) { - 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 {id:?} resolved multiple times ({prev_res:?} before, {res:?} now)") } @@ -2428,7 +2428,7 @@ fn record_lifetime_res( #[instrument(level = "debug", skip(self))] fn record_lifetime_param(&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)" ) @@ -2456,7 +2456,9 @@ fn resolve_fn_signature( 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 @@ -2635,11 +2637,11 @@ fn visit_ty(&mut self, ty: &'ra Ty) { 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); } @@ -5212,7 +5214,7 @@ fn resolve_expr(&mut self, expr: &'ast Expr, parent: Option<&'ast Expr>) { 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 f5f4c9e6e258..3bfa415bf75d 100644 --- a/compiler/rustc_resolve/src/lib.rs +++ b/compiler/rustc_resolve/src/lib.rs @@ -1380,10 +1380,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. extra_lifetime_params_map: NodeMap> = Default::default(), @@ -1533,8 +1529,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(), @@ -2017,13 +2011,10 @@ pub fn into_outputs(self) -> ResolverOutputs<'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, 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,