rust-lang/rust · #162120
Introduce `PerOwnerLoweringState`
compiler/rustc_ast_lowering/src/delegation/attributes.rs3 + / 3 −
@@ -43,17 +43,17 @@ impl<'hir> LoweringContext<'_, 'hir> { let &DelegationResolution { span, sig_id, .. } = resolution; const PARENT_ID: hir::ItemLocalId = hir::ItemLocalId::ZERO;- let new_attrs = self.create_new_attrs(span, sig_id, self.attrs.get(&PARENT_ID));+ let new_attrs = self.create_new_attrs(span, sig_id, self.curr_owner.attrs.get(&PARENT_ID)); if !new_attrs.is_empty() {- let new_attrs = match self.attrs.get(&PARENT_ID) {+ let new_attrs = match self.curr_owner.attrs.get(&PARENT_ID) { Some(existing_attrs) => self.arena.alloc_from_iter( existing_attrs.iter().map(|a| a.clone()).chain(new_attrs.into_iter()), ), None => self.arena.alloc_from_iter(new_attrs.into_iter()), }; - self.attrs.insert(PARENT_ID, new_attrs);+ self.curr_owner.attrs.insert(PARENT_ID, new_attrs); } } compiler/rustc_ast_lowering/src/delegation/generics.rs1 + / 1 −
@@ -587,7 +587,7 @@ impl<'hir> LoweringContext<'_, 'hir> { }; // Important: we don't use `self.next_id()` as we want to execute- // `lower_node_id` routine so param's id is added to `self.children`.+ // `lower_node_id` routine so param's id is added to `self.curr_owner.children`. let hir_id = self.lower_node_id(node_id); Some(hir::GenericParam {compiler/rustc_ast_lowering/src/delegation/mod.rs6 + / 4 −
@@ -140,9 +140,11 @@ impl<'hir> LoweringContext<'_, 'hir> { let id = match source { DelegationSource::Single => None, DelegationSource::List(expn_id) => Some(expn_id),- DelegationSource::Glob => {- Some(self.tcx.expn_that_defined(self.owner.def_id).expect_local())- }+ DelegationSource::Glob => Some(+ self.tcx+ .expn_that_defined(self.curr_owner.owner.def_id)+ .expect_local(),+ ), }; id.map(|id| (id, unused_target_expr))@@ -335,7 +337,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let overwrites = self_resolver.overwrites; // Target expr needs to lower `self` path.- self.ident_and_label_to_local_id.insert(pat_node_id, param_local_id);+ self.curr_owner.ident_and_label_to_local_id.insert(pat_node_id, param_local_id); let block = cfg_select! { debug_assertions => {compiler/rustc_ast_lowering/src/delegation/resolution.rs2 + / 2 −
@@ -73,7 +73,7 @@ pub(super) mod resolver { #[inline] pub(crate) fn owner_id(&self) -> LocalDefId {- self.0.owner.def_id+ self.0.curr_owner.owner.def_id } /// (from `tests\ui\delegation\target-expr-removal-defs-inside.rs`):@@ -91,7 +91,7 @@ pub(super) mod resolver { #[inline] pub(crate) fn is_definition(&self, id: NodeId) -> bool { self.0.resolver.owners.contains_key(&id)- || self.0.owner.node_id_to_def_id.contains_key(&id)+ || self.0.curr_owner.owner.node_id_to_def_id.contains_key(&id) } #[inline]compiler/rustc_ast_lowering/src/expr.rs9 + / 8 −
@@ -172,7 +172,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } // Merge attributes into the inner expression. if !e.attrs.is_empty() {- let old_attrs = self.attrs.get(&ex.hir_id.local_id).copied().unwrap_or(&[]);+ let old_attrs =+ self.curr_owner.attrs.get(&ex.hir_id.local_id).copied().unwrap_or(&[]); let new_attrs = self .lower_attrs_vec(&e.attrs, e.span, ex.hir_id, Target::from_expr(e)) .into_iter()@@ -181,7 +182,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if new_attrs.is_empty() { return ex; }- self.attrs.insert(ex.hir_id.local_id, new_attrs);+ self.curr_owner.attrs.insert(ex.hir_id.local_id, new_attrs); } return ex; }@@ -884,15 +885,15 @@ impl<'hir> LoweringContext<'_, 'hir> { /// `inner_hir_id` in case the `async_fn_track_caller` feature is enabled. pub(super) fn maybe_forward_track_caller(&mut self, outer_hir_id: HirId, inner_hir_id: HirId) { if self.tcx.features().async_fn_track_caller()- && let Some(attrs) = self.attrs.get(&outer_hir_id.local_id)+ && let Some(attrs) = self.curr_owner.attrs.get(&outer_hir_id.local_id) && let Some(t) = attrs.iter().find(|a| { matches!( a, rustc_attr_ir::Attribute::Parsed(rustc_attr_ir::AttributeKind::TrackCaller(_)) ) }) {- self.attrs.insert(inner_hir_id.local_id, std::slice::from_ref(t));+ self.curr_owner.attrs.insert(inner_hir_id.local_id, std::slice::from_ref(t)); } } @@ -1505,16 +1506,16 @@ impl<'hir> LoweringContext<'_, 'hir> { dest_hir_id: hir::HirId, ) -> Option<Label> { let label = opt_label?;- self.ident_and_label_to_local_id.insert(dest_id, dest_hir_id.local_id);+ self.curr_owner.ident_and_label_to_local_id.insert(dest_id, dest_hir_id.local_id); Some(Label { ident: self.lower_ident(label.ident) }) } 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.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 };+ if let Some(loop_id) = self.curr_owner.owner.get_label_res(id) {+ let local_id = self.curr_owner.ident_and_label_to_local_id[&loop_id];+ let loop_hir_id = HirId { owner: self.curr_owner.owner_id, local_id }; Ok(loop_hir_id) } else { Err(hir::LoopIdError::UnresolvedLabel)compiler/rustc_ast_lowering/src/item.rs20 + / 22 −
@@ -61,17 +61,15 @@ impl<'hir> ItemLowerer<'_, 'hir> { let mut lctx = LoweringContext::new(self.tcx, self.resolver, owner); let item = f(&mut lctx);- debug_assert_eq!(lctx.current_hir_id_owner, item.def_id());-- let info = lctx.make_owner_info(item); + let info = lctx.curr_owner.into_owner_info(self.tcx, item); hir::MaybeOwner::Owner(lctx.arena.alloc(info)) } #[instrument(level = "debug", skip(self, c))] pub(super) fn lower_crate(&mut self, c: &Crate) -> hir::MaybeOwner<'hir> { self.with_lctx(CRATE_NODE_ID, |lctx| {- debug_assert_eq!(lctx.current_hir_id_owner, CRATE_OWNER_ID);+ debug_assert_eq!(lctx.curr_owner.owner_id, CRATE_OWNER_ID); let module = lctx.lower_mod(&c.items, &c.spans); lctx.lower_attrs(hir::CRATE_HIR_ID, &c.attrs, c.spans.inner_span, Target::Crate); hir::OwnerNode::Crate(module)@@ -206,7 +204,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_item(&mut self, i: &Item) -> &'hir hir::Item<'hir> {- let owner_id = self.current_hir_id_owner;+ let owner_id = self.curr_owner.owner_id; let hir_id: HirId = owner_id.into(); let vis_span = self.lower_span(i.vis.span); @@ -399,7 +397,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ty, ImplTraitContext::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias {- parent: this.owner.def_id,+ parent: this.curr_owner.owner.def_id, in_assoc_ty: false, }, },@@ -547,7 +545,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ItemKind::MacroDef(ident, MacroDef { body, macro_rules, eii_declaration: _ }) => { let ident = self.lower_ident(*ident); let body = Box::new(self.lower_delim_args(body));- let def_id = self.owner.def_id;+ let def_id = self.curr_owner.owner.def_id; let def_kind = self.tcx.def_kind(def_id); let DefKind::Macro(macro_kinds) = def_kind else { unreachable!(@@ -695,7 +693,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // `ItemLocalId` and the new owner. (See `lower_node_id`) let kind = this.lower_use_tree(use_tree, &prefix, id, vis_span, attrs); if !attrs.is_empty() {- this.attrs.insert(hir::ItemLocalId::ZERO, attrs);+ this.curr_owner.attrs.insert(hir::ItemLocalId::ZERO, attrs); } let item = hir::Item {@@ -731,7 +729,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_foreign_item(&mut self, i: &ForeignItem) -> &'hir hir::ForeignItem<'hir> {- let owner_id = self.current_hir_id_owner;+ let owner_id = self.curr_owner.owner_id; let hir_id: HirId = owner_id.into(); let attrs = self.lower_attrs(hir_id, &i.attrs, i.span, Target::from_foreign_item_kind(&i.kind));@@ -914,7 +912,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_trait_item(&mut self, i: &AssocItem) -> &'hir hir::TraitItem<'hir> {- let trait_item_def_id = self.current_hir_id_owner;+ let trait_item_def_id = self.curr_owner.owner_id; let hir_id: HirId = trait_item_def_id.into(); let attrs = self.lower_attrs( hir_id,@@ -1169,7 +1167,7 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_impl_item(&mut self, i: &AssocItem) -> &'hir hir::ImplItem<'hir> {- let owner_id = self.current_hir_id_owner;+ let owner_id = self.curr_owner.owner_id; let hir_id: HirId = owner_id.into(); let parent_id = self.tcx.local_parent(owner_id.def_id); let is_in_trait_impl =@@ -1258,7 +1256,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ty, ImplTraitContext::OpaqueTy { origin: hir::OpaqueTyOrigin::TyAlias {- parent: this.owner.def_id,+ parent: this.curr_owner.owner.def_id, in_assoc_ty: true, }, },@@ -1336,8 +1334,8 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> hir::BodyId { let body = hir::Body { params, value: self.arena.alloc(value) }; let id = body.id();- assert_eq!(id.hir_id.owner, self.current_hir_id_owner);- self.bodies.push((id.hir_id.local_id, self.arena.alloc(body)));+ assert_eq!(id.hir_id.owner, self.curr_owner.owner_id);+ self.curr_owner.bodies.push((id.hir_id.local_id, self.arena.alloc(body))); id } @@ -1545,7 +1543,7 @@ impl<'hir> LoweringContext<'_, 'hir> { // // If this is the simple case, this parameter will end up being the same as the // original parameter, but with a different pattern id.- let stmt_attrs = self.attrs.get(¶meter.hir_id.local_id).copied();+ let stmt_attrs = self.curr_owner.attrs.get(¶meter.hir_id.local_id).copied(); let (new_parameter_pat, new_parameter_id) = self.pat_ident(desugared_span, ident); let new_parameter = hir::Param { hir_id: parameter.hir_id,@@ -1883,8 +1881,8 @@ impl<'hir> LoweringContext<'_, 'hir> { itctx: ImplTraitContext, f: impl FnOnce(&mut Self) -> T, ) -> (&'hir hir::Generics<'hir>, T) {- assert!(self.impl_trait_defs.is_empty());- assert!(self.impl_trait_bounds.is_empty());+ assert!(self.curr_owner.impl_trait_defs.is_empty());+ assert!(self.curr_owner.impl_trait_bounds.is_empty()); let mut predicates: SmallVec<[hir::WherePredicate<'hir>; 4]> = SmallVec::new(); // We need to make sure that generic params don't have multiple relaxed bounds for the same trait@@ -1914,7 +1912,7 @@ impl<'hir> LoweringContext<'_, 'hir> { .collect(); // Introduce extra lifetimes if late resolution tells us to.- let extra_lifetimes = self.owner.extra_lifetime_params(self.owner.id);+ let extra_lifetimes = self.curr_owner.owner.extra_lifetime_params(self.curr_owner.owner.id); params.extend(extra_lifetimes.into_iter().map(|&(ident, node_id, kind)| { self.lifetime_res_to_generic_param( ident,@@ -1929,10 +1927,10 @@ impl<'hir> LoweringContext<'_, 'hir> { let span = self.lower_span(generics.span); let res = f(self); - let impl_trait_defs = std::mem::take(&mut self.impl_trait_defs);+ let impl_trait_defs = std::mem::take(&mut self.curr_owner.impl_trait_defs); params.extend(impl_trait_defs.into_iter()); - let impl_trait_bounds = std::mem::take(&mut self.impl_trait_bounds);+ let impl_trait_bounds = std::mem::take(&mut self.curr_owner.impl_trait_bounds); predicates.extend(impl_trait_bounds.into_iter()); let lowered_generics = self.arena.alloc(hir::Generics {@@ -1951,7 +1949,7 @@ impl<'hir> LoweringContext<'_, 'hir> { hir_id: HirId, define_opaque: &Option<ThinVec<(NodeId, Path)>>, ) {- assert_eq!(self.define_opaque, None);+ assert_eq!(self.curr_owner.define_opaque, None); assert!(hir_id.is_owner()); let Some(define_opaque) = define_opaque.as_ref() else { return;@@ -1972,7 +1970,7 @@ impl<'hir> LoweringContext<'_, 'hir> { Some((self.lower_span(path.span), did)) }); let define_opaque = self.arena.alloc_from_iter(define_opaque);- self.define_opaque = Some(define_opaque);+ self.curr_owner.define_opaque = Some(define_opaque); } pub(super) fn lower_generic_bound_predicate(compiler/rustc_ast_lowering/src/lib.rs191 + / 202 −
@@ -131,36 +131,155 @@ pub(crate) mod re_lowering { ctx: &mut LoweringContext<'a, 'hir>, op: impl FnOnce(&mut LoweringContext<'a, 'hir>) -> TRes, ) -> TRes {- assert!(!ctx.relowering_checker.can_relower, "reentrant relowering is not supported");+ assert!(+ !ctx.curr_owner.relowering_checker.can_relower,+ "reentrant relowering is not supported"+ ); - ctx.relowering_checker.can_relower = true;+ ctx.curr_owner.relowering_checker.can_relower = true; let res = op(ctx); - ctx.relowering_checker.can_relower = false;+ ctx.curr_owner.relowering_checker.can_relower = false; res } } } -struct LoweringContext<'a, 'hir> {- tcx: TyCtxt<'hir>,- resolver: &'a ResolverAstLowering<'hir>,- current_disambiguator: PerParentDisambiguatorState,+struct PerOwnerLoweringState<'a, 'hir> {+ // -- Identity --+ owner: &'a PerOwnerResolverData<'hir>,+ owner_id: hir::OwnerId,+ disambiguator: PerParentDisambiguatorState, - /// Used to allocate HIR nodes.- arena: &'hir hir::Arena<'hir>,+ // -- HirId allocation --+ item_local_id_counter: hir::ItemLocalId,+ /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR+ /// owner.+ ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,+ /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering+ /// check.+ #[cfg(debug_assertions)]+ relowering_checker: re_lowering::ReloweringChecker, + // -- Accumulated outputs --+ /// Attributes inside the owner being lowered.+ attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>, /// Bodies inside the owner being lowered. bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>, /// `#[define_opaque]` attributes define_opaque: Option<&'hir [(Span, LocalDefId)]>,- /// Attributes inside the owner being lowered.- attrs: SortedMap<hir::ItemLocalId, &'hir [hir::Attribute]>,+ trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>,+ delayed_lints: Vec<DelayedLint>, /// Collect items that were created by lowering the current owner. children: LocalDefIdMap<hir::MaybeOwner<'hir>>, + // -- Transient --+ impl_trait_defs: Vec<hir::GenericParam<'hir>>,+ impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,+}++impl<'a, 'hir> PerOwnerLoweringState<'a, 'hir> {+ fn new(resolver: &'a ResolverAstLowering<'hir>, owner: NodeId) -> Self {+ let owner = &resolver.owners[&owner];++ let disambiguator = resolver+ .disambiguators+ .get(&owner.def_id)+ .map(|s| s.steal())+ .unwrap_or_else(|| PerParentDisambiguatorState::new(owner.def_id));++ PerOwnerLoweringState {+ owner,+ owner_id: hir::OwnerId { def_id: owner.def_id },+ disambiguator,+ // 0 corresponds to `owner` lowered as `owner_id`, and we never call+ // `lower_node_id(owner)`.+ item_local_id_counter: hir::ItemLocalId::new(1),+ ident_and_label_to_local_id: Default::default(),+ #[cfg(debug_assertions)]+ relowering_checker: Default::default(),+ attrs: SortedMap::default(),+ bodies: Vec::new(),+ define_opaque: None,+ trait_map: Default::default(),+ delayed_lints: Vec::new(),+ children: LocalDefIdMap::default(),+ impl_trait_defs: Vec::new(),+ impl_trait_bounds: Vec::new(),+ }+ }++ fn into_owner_info(+ self,+ tcx: TyCtxt<'hir>,+ node: hir::OwnerNode<'hir>,+ ) -> &'hir hir::OwnerInfo<'hir> {+ assert_eq!(self.owner_id, node.def_id());+ assert!(self.impl_trait_defs.is_empty());+ assert!(self.impl_trait_bounds.is_empty());++ let attrs = self.attrs;+ let mut bodies = self.bodies;+ let define_opaque = self.define_opaque;+ let trait_map = self.trait_map;+ let delayed_lints = Steal::new(self.delayed_lints.into_boxed_slice());+ let children = self.children;++ #[cfg(debug_assertions)]+ for (id, attrs) in attrs.iter() {+ // Verify that we do not store empty slices in the map.+ if attrs.is_empty() {+ panic!("Stored empty attributes for {:?}", id);+ }+ }++ bodies.sort_by_key(|(k, _)| *k);+ let bodies = SortedMap::from_presorted_elements(bodies);++ // Don't hash unless necessary, because it's expensive.+ let rustc_middle::hir::Hashes { bodies_hash, attrs_hash } =+ tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);+ let num_nodes = self.item_local_id_counter.as_usize();+ let (nodes, parenting) = index::index_hir(tcx, node, &bodies, num_nodes);+ let nodes = hir::OwnerNodes { opt_hash: bodies_hash, nodes, bodies };+ let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };++ let opt_hash = tcx.needs_hir_hash().then(|| {+ tcx.with_stable_hashing_context(|mut hcx| {+ let mut stable_hasher = StableHasher::new();+ bodies_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);+ attrs_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);+ // Do not hash delayed_lints.+ parenting.stable_hash(&mut hcx, &mut stable_hasher);+ trait_map.stable_hash(&mut hcx, &mut stable_hasher);+ children.stable_hash(&mut hcx, &mut stable_hasher);+ stable_hasher.finish()+ })+ });++ tcx.hir_arena.alloc(hir::OwnerInfo {+ opt_hash,+ nodes,+ parenting,+ attrs,+ trait_map,+ delayed_lints,+ children,+ })+ }+}++struct LoweringContext<'a, 'hir> {+ tcx: TyCtxt<'hir>,+ resolver: &'a ResolverAstLowering<'hir>,++ curr_owner: PerOwnerLoweringState<'a, 'hir>,++ /// Used to allocate HIR nodes.+ arena: &'hir hir::Arena<'hir>,+ contract_ensures: Option<(Span, Ident, HirId)>, coroutine_kind: Option<hir::CoroutineKind>,@@ -178,19 +297,6 @@ struct LoweringContext<'a, 'hir> { is_in_loop_condition: bool, is_in_dyn_type: bool, - current_hir_id_owner: hir::OwnerId,- owner: &'a PerOwnerResolverData<'hir>,- item_local_id_counter: hir::ItemLocalId,- trait_map: ItemLocalMap<&'hir [TraitCandidate<'hir>]>,-- impl_trait_defs: Vec<hir::GenericParam<'hir>>,- impl_trait_bounds: Vec<hir::WherePredicate<'hir>>,-- /// NodeIds of pattern identifiers and labelled nodes that are lowered inside the current HIR owner.- ident_and_label_to_local_id: NodeMap<hir::ItemLocalId>,- /// NodeIds that are lowered inside the current HIR owner. Only used for duplicate lowering check.- #[cfg(debug_assertions)]- relowering_checker: re_lowering::ReloweringChecker, /// The `NodeId` space is split in two. /// `0..resolver.next_node_id` are created by the resolver on the AST. /// The higher part `resolver.next_node_id..next_node_id` are created during lowering.@@ -211,8 +317,6 @@ struct LoweringContext<'a, 'hir> { allow_for_await: Arc<[Symbol]>, allow_async_fn_traits: Arc<[Symbol]>, - delayed_lints: Vec<DelayedLint>,- /// Stack of `move(...)` collection states. A plain closure body pushes /// `Some`, so `move(...)` expressions can record the generated locals they /// should lower to. Nested bodies that cannot use `move(...)` push `None`.@@ -223,37 +327,14 @@ struct LoweringContext<'a, 'hir> { impl<'a, 'hir> LoweringContext<'a, 'hir> { fn new(tcx: TyCtxt<'hir>, resolver: &'a ResolverAstLowering<'hir>, owner: NodeId) -> Self {- let current_ast_owner = &resolver.owners[&owner];- let current_hir_id_owner = hir::OwnerId { def_id: current_ast_owner.def_id };- let current_disambiguator = resolver- .disambiguators- .get(¤t_hir_id_owner.def_id)- .map(|s| s.steal())- .unwrap_or_else(|| PerParentDisambiguatorState::new(current_hir_id_owner.def_id));- Self { tcx, resolver,- current_disambiguator,- owner: current_ast_owner,+ curr_owner: PerOwnerLoweringState::new(resolver, owner), arena: tcx.hir_arena, - // HirId handling.- bodies: Vec::new(),- define_opaque: None,- attrs: SortedMap::default(),- children: LocalDefIdMap::default(), contract_ensures: None,- current_hir_id_owner,- // 0 corresponds to `owner` lowered as `current_hir_id_owner`,- // and we never call `lower_node_id(owner)`.- item_local_id_counter: hir::ItemLocalId::new(1),- ident_and_label_to_local_id: Default::default(),-- #[cfg(debug_assertions)]- relowering_checker: Default::default(), - trait_map: Default::default(), next_node_id: resolver.next_node_id, node_id_to_def_id: NodeMap::default(), partial_res_overrides: NodeMap::default(),@@ -266,8 +347,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { coroutine_kind: None, task_context: None, current_item: None,- impl_trait_defs: Vec::new(),- impl_trait_bounds: Vec::new(), allow_contracts: [sym::contracts_internals].into(), allow_try_trait: [ sym::try_trait_v2,@@ -295,7 +374,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { tcx.registered_attr_tools(()), ShouldEmit::ErrorsAndLints { recovery: Recovery::Allowed }, ),- delayed_lints: Vec::new(), } } @@ -746,7 +824,7 @@ impl<'hir> LoweringContext<'_, 'hir> { def_kind: DefKind, span: Span, ) -> LocalDefId {- let parent = self.current_hir_id_owner.def_id;+ let parent = self.curr_owner.owner_id.def_id; assert_ne!(node_id, ast::DUMMY_NODE_ID); assert!( self.opt_local_def_id(node_id).is_none(),@@ -759,7 +837,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let def_id = self .tcx .at(span)- .create_def(parent, name, def_kind, None, &mut self.current_disambiguator)+ .create_def(parent, name, def_kind, None, &mut self.curr_owner.disambiguator) .def_id(); debug!("create_def: def_id_to_node_id[{:?}] <-> {:?}", def_id, node_id);@@ -781,7 +859,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn opt_local_def_id(&self, node: NodeId) -> Option<LocalDefId> { self.node_id_to_def_id .get(&node)- .or_else(|| self.owner.node_id_to_def_id.get(&node))+ .or_else(|| self.curr_owner.owner.node_id_to_def_id.get(&node)) .copied() } @@ -813,132 +891,40 @@ impl<'hir> LoweringContext<'_, 'hir> { } /// Freshen the `LoweringContext` and ready it to lower a nested item.- /// The lowered item is registered into `self.children`.+ /// The lowered item is registered into `self.curr_owner.children`. /// /// This function sets up `HirId` lowering infrastructure,- /// and stashes the shared mutable state to avoid pollution by the closure.+ /// and stashes the per-owner state to avoid pollution by the closure. #[instrument(level = "debug", skip(self, f))] fn with_hir_id_owner( &mut self, owner: NodeId, f: impl FnOnce(&mut Self) -> hir::OwnerNode<'hir>, ) {- let owner_id = self.owner_id(owner);- let def_id = owner_id.def_id;-- let new_disambig = self- .resolver- .disambiguators- .get(&def_id)- .map(|s| s.steal())- .unwrap_or_else(|| PerParentDisambiguatorState::new(def_id));-- let disambiguator = mem::replace(&mut self.current_disambiguator, new_disambig);- let current_ast_owner = mem::replace(&mut self.owner, &self.resolver.owners[&owner]);- let current_attrs = mem::take(&mut self.attrs);- let current_bodies = mem::take(&mut self.bodies);- let current_define_opaque = mem::take(&mut self.define_opaque);- let current_ident_and_label_to_local_id = mem::take(&mut self.ident_and_label_to_local_id);-- #[cfg(debug_assertions)]- let current_relowering_checker = mem::take(&mut self.relowering_checker);- let current_trait_map = mem::take(&mut self.trait_map);- let current_owner = mem::replace(&mut self.current_hir_id_owner, owner_id);- let current_local_counter =- mem::replace(&mut self.item_local_id_counter, hir::ItemLocalId::new(1));- let current_impl_trait_defs = mem::take(&mut self.impl_trait_defs);- let current_impl_trait_bounds = mem::take(&mut self.impl_trait_bounds);- let current_delayed_lints = mem::take(&mut self.delayed_lints);- let current_children = mem::take(&mut self.children);+ let child_owner = PerOwnerLoweringState::new(self.resolver, owner);+ let parent_owner = mem::replace(&mut self.curr_owner, child_owner); // Do not reset `next_node_id` and `node_id_to_def_id`: // we want `f` to be able to refer to the `LocalDefId`s that the caller created. // and the caller to refer to some of the subdefinitions' nodes' `LocalDefId`s. // Always allocate the first `HirId` for the owner itself. #[cfg(debug_assertions)]- self.relowering_checker.assert_node_is_not_relowered(owner, hir::ItemLocalId::ZERO);+ self.curr_owner+ .relowering_checker+ .assert_node_is_not_relowered(owner, hir::ItemLocalId::ZERO); let item = f(self);- assert_eq!(owner_id, item.def_id());- // `f` should have consumed all the elements in these vectors when constructing `item`.- assert!(self.impl_trait_defs.is_empty());- assert!(self.impl_trait_bounds.is_empty());- let info = self.make_owner_info(item);+ let completed_child_owner = mem::replace(&mut self.curr_owner, parent_owner);+ let owner_id = completed_child_owner.owner_id;+ let info = completed_child_owner.into_owner_info(self.tcx, item); - self.current_disambiguator = disambiguator;- self.owner = current_ast_owner;- self.attrs = current_attrs;- self.bodies = current_bodies;- self.define_opaque = current_define_opaque;- self.ident_and_label_to_local_id = current_ident_and_label_to_local_id;+ self.curr_owner+ .children+ .extend_unord(info.children.items().map(|(&def_id, &info)| (def_id, info))); - #[cfg(debug_assertions)]- {- self.relowering_checker = current_relowering_checker;- }- self.trait_map = current_trait_map;- self.current_hir_id_owner = current_owner;- self.item_local_id_counter = current_local_counter;- self.impl_trait_defs = current_impl_trait_defs;- self.impl_trait_bounds = current_impl_trait_bounds;- self.delayed_lints = current_delayed_lints;- self.children = current_children;- self.children.extend_unord(info.children.items().map(|(&def_id, &info)| (def_id, info)));-- debug_assert!(!self.children.contains_key(&owner_id.def_id));- self.children.insert(owner_id.def_id, hir::MaybeOwner::Owner(info));- }-- fn make_owner_info(&mut self, node: hir::OwnerNode<'hir>) -> &'hir hir::OwnerInfo<'hir> {- let attrs = mem::take(&mut self.attrs);- let mut bodies = mem::take(&mut self.bodies);- let define_opaque = mem::take(&mut self.define_opaque);- let trait_map = mem::take(&mut self.trait_map);- let delayed_lints = Steal::new(mem::take(&mut self.delayed_lints).into_boxed_slice());- let children = mem::take(&mut self.children);-- #[cfg(debug_assertions)]- for (id, attrs) in attrs.iter() {- // Verify that we do not store empty slices in the map.- if attrs.is_empty() {- panic!("Stored empty attributes for {:?}", id);- }- }-- bodies.sort_by_key(|(k, _)| *k);- let bodies = SortedMap::from_presorted_elements(bodies);-- // Don't hash unless necessary, because it's expensive.- let rustc_middle::hir::Hashes { bodies_hash, attrs_hash } =- self.tcx.hash_owner_nodes(node, &bodies, &attrs, define_opaque);- let num_nodes = self.item_local_id_counter.as_usize();- let (nodes, parenting) = index::index_hir(self.tcx, node, &bodies, num_nodes);- let nodes = hir::OwnerNodes { opt_hash: bodies_hash, nodes, bodies };- let attrs = hir::AttributeMap { map: attrs, opt_hash: attrs_hash, define_opaque };-- let opt_hash = self.tcx.needs_hir_hash().then(|| {- self.tcx.with_stable_hashing_context(|mut hcx| {- let mut stable_hasher = StableHasher::new();- bodies_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);- attrs_hash.unwrap().stable_hash(&mut hcx, &mut stable_hasher);- // Do not hash delayed_lints.- parenting.stable_hash(&mut hcx, &mut stable_hasher);- trait_map.stable_hash(&mut hcx, &mut stable_hasher);- children.stable_hash(&mut hcx, &mut stable_hasher);- stable_hasher.finish()- })- });-- self.arena.alloc(hir::OwnerInfo {- opt_hash,- nodes,- parenting,- attrs,- trait_map,- delayed_lints,- children,- })+ debug_assert!(!self.curr_owner.children.contains_key(&owner_id.def_id));+ self.curr_owner.children.insert(owner_id.def_id, hir::MaybeOwner::Owner(info)); } /// This method allocates a new `HirId` for the given `NodeId`.@@ -950,42 +936,43 @@ impl<'hir> LoweringContext<'_, 'hir> { fn lower_node_id(&mut self, ast_node_id: NodeId) -> HirId { assert_ne!(ast_node_id, DUMMY_NODE_ID); - let owner = self.current_hir_id_owner;- let local_id = self.item_local_id_counter;+ let owner = self.curr_owner.owner_id;+ let local_id = self.curr_owner.item_local_id_counter; assert_ne!(local_id, hir::ItemLocalId::ZERO);- self.item_local_id_counter.increment_by(1);+ self.curr_owner.item_local_id_counter.increment_by(1); let hir_id = HirId { owner, local_id }; if let Some(def_id) = self.opt_local_def_id(ast_node_id) {- self.children.insert(def_id, hir::MaybeOwner::NonOwner(hir_id));+ self.curr_owner.children.insert(def_id, hir::MaybeOwner::NonOwner(hir_id)); } - if let Some(traits) = self.owner.trait_map.get(&ast_node_id) {- self.trait_map.insert(hir_id.local_id, *traits);+ if let Some(traits) = self.curr_owner.owner.trait_map.get(&ast_node_id) {+ self.curr_owner.trait_map.insert(hir_id.local_id, *traits); } // Check whether the same `NodeId` is lowered more than once. #[cfg(debug_assertions)]- self.relowering_checker.assert_node_is_not_relowered(ast_node_id, local_id);+ self.curr_owner.relowering_checker.assert_node_is_not_relowered(ast_node_id, local_id); hir_id } /// Generate a new `HirId` without a backing `NodeId`. #[instrument(level = "debug", skip(self), ret)] fn next_id(&mut self) -> HirId {- let owner = self.current_hir_id_owner;- let local_id = self.item_local_id_counter;+ let owner = self.curr_owner.owner_id;+ let local_id = self.curr_owner.item_local_id_counter; assert_ne!(local_id, hir::ItemLocalId::ZERO);- self.item_local_id_counter.increment_by(1);+ self.curr_owner.item_local_id_counter.increment_by(1); HirId { owner, local_id } } #[instrument(level = "trace", skip(self))] fn lower_res(&mut self, res: Res<NodeId>) -> Res { let res: Result<Res, ()> = res.apply_id(|id| {- let owner = self.current_hir_id_owner;- let local_id = self.ident_and_label_to_local_id.get(&id).copied().ok_or(())?;+ let owner = self.curr_owner.owner_id;+ let local_id =+ self.curr_owner.ident_and_label_to_local_id.get(&id).copied().ok_or(())?; Ok(HirId { owner, local_id }) }); trace!(?res);@@ -1003,8 +990,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn lower_import_res(&mut self, id: NodeId, span: Span) -> PerNS<Option<Res>> {- debug_assert_eq!(id, self.owner.id);- let per_ns = self.owner.import_res.map(|res| res.map(|res| self.lower_res(res)));+ debug_assert_eq!(id, self.curr_owner.owner.id);+ let per_ns = self.curr_owner.owner.import_res.map(|res| res.map(|res| self.lower_res(res))); if per_ns.is_empty() { // Propagate the error to all namespaces, just to be sure. self.dcx().span_delayed_bug(span, "no resolution for an import");@@ -1062,7 +1049,7 @@ impl<'hir> LoweringContext<'_, 'hir> { fn span_lowerer(&self) -> SpanLowerer { SpanLowerer { is_incremental: self.tcx.sess.opts.incremental.is_some(),- def_id: self.current_hir_id_owner.def_id,+ def_id: self.curr_owner.owner_id.def_id, } } @@ -1122,7 +1109,7 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> &'hir [hir::GenericParam<'hir>] { // Start by creating params for extra lifetimes params, as this creates the definitions // that may be referred to by the AST inside `generic_params`.- let extra_lifetimes = self.owner.extra_lifetime_params(binder);+ let extra_lifetimes = self.curr_owner.owner.extra_lifetime_params(binder); debug!(?extra_lifetimes); let extra_lifetimes: Vec<_> = extra_lifetimes .iter()@@ -1201,7 +1188,7 @@ impl<'hir> LoweringContext<'_, 'hir> { self.lower_attrs_vec(attrs, self.lower_span(target_span), id, target); lowered_attrs.extend(extra_hir_attributes.iter().cloned()); - assert_eq!(id.owner, self.current_hir_id_owner);+ assert_eq!(id.owner, self.curr_owner.owner_id); let ret = self.arena.alloc_from_iter(lowered_attrs); // this is possible if an item contained syntactical attribute,@@ -1213,7 +1200,7 @@ impl<'hir> LoweringContext<'_, 'hir> { if ret.is_empty() { &[] } else {- self.attrs.insert(id.local_id, ret);+ self.curr_owner.attrs.insert(id.local_id, ret); ret } }@@ -1233,7 +1220,7 @@ impl<'hir> LoweringContext<'_, 'hir> { target, |s| l.lower(s), |lint_id, span, kind| {- self.delayed_lints.push(DelayedLint {+ self.curr_owner.delayed_lints.push(DelayedLint { lint_id, id: target_hir_id, span,@@ -1249,11 +1236,11 @@ impl<'hir> LoweringContext<'_, 'hir> { } fn alias_attrs(&mut self, id: HirId, target_id: HirId) {- assert_eq!(id.owner, self.current_hir_id_owner);- assert_eq!(target_id.owner, self.current_hir_id_owner);- if let Some(&a) = self.attrs.get(&target_id.local_id) {+ assert_eq!(id.owner, self.curr_owner.owner_id);+ assert_eq!(target_id.owner, self.curr_owner.owner_id);+ if let Some(&a) = self.curr_owner.attrs.get(&target_id.local_id) { assert!(!a.is_empty());- self.attrs.insert(id.local_id, a);+ self.curr_owner.attrs.insert(id.local_id, a); } } @@ -1706,9 +1693,9 @@ impl<'hir> LoweringContext<'_, 'hir> { ident, bounds, );- self.impl_trait_defs.push(param);+ self.curr_owner.impl_trait_defs.push(param); if let Some(bounds) = bounds {- self.impl_trait_bounds.push(bounds);+ self.curr_owner.impl_trait_bounds.push(bounds); } path }@@ -1812,7 +1799,7 @@ impl<'hir> LoweringContext<'_, 'hir> { None => { let id = if let Some(LifetimeRes::ElidedAnchor { start, end }) =- self.owner.get_lifetime_res(t.id)+ self.curr_owner.owner.get_lifetime_res(t.id) { assert_eq!(start.plus(1), end); start@@ -1996,27 +1983,27 @@ impl<'hir> LoweringContext<'_, 'hir> { let output = match coro { Some(coro) => {- let fn_def_id = self.owner.def_id;+ let fn_def_id = self.curr_owner.owner.def_id; self.lower_coroutine_fn_ret_ty(&decl.output, fn_def_id, coro, kind) } None => match &decl.output { FnRetTy::Ty(ty) => { let itctx = match kind { FnDeclKind::Fn | FnDeclKind::Inherent => ImplTraitContext::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn {- parent: self.owner.def_id,+ parent: self.curr_owner.owner.def_id, in_trait_or_impl: None, }, }, FnDeclKind::Trait => ImplTraitContext::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn {- parent: self.owner.def_id,+ parent: self.curr_owner.owner.def_id, in_trait_or_impl: Some(hir::RpitContext::Trait), }, }, FnDeclKind::Impl => ImplTraitContext::OpaqueTy { origin: hir::OpaqueTyOrigin::FnReturn {- parent: self.owner.def_id,+ parent: self.curr_owner.owner.def_id, in_trait_or_impl: Some(hir::RpitContext::TraitImpl), }, },@@ -2061,7 +2048,8 @@ impl<'hir> LoweringContext<'_, 'hir> { } })) .set_lifetime_elision_allowed(- self.owner.id == fn_node_id && self.owner.lifetime_elision_allowed,+ self.curr_owner.owner.id == fn_node_id+ && self.curr_owner.owner.lifetime_elision_allowed, ) .set_c_variadic(c_variadic) .set_splatted(splatted, inputs.len())@@ -2229,7 +2217,7 @@ impl<'hir> LoweringContext<'_, 'hir> { source: LifetimeSource, syntax: LifetimeSyntax, ) -> &'hir hir::Lifetime {- let res = if let Some(res) = self.owner.get_lifetime_res(id) {+ let res = if let Some(res) = self.curr_owner.owner.get_lifetime_res(id) { match res { LifetimeRes::Param { param, .. } => hir::LifetimeKind::Param(param), LifetimeRes::Fresh { param, .. } => {@@ -2315,12 +2303,13 @@ 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.owner.get_lifetime_res(param.id) {- ParamName::Error(ident)- } else {- ParamName::Plain(ident)- };+ let param_name = if let Some(LifetimeRes::Error(..)) =+ self.curr_owner.owner.get_lifetime_res(param.id)+ {+ ParamName::Error(ident)+ } else {+ ParamName::Plain(ident)+ }; let kind = hir::GenericParamKind::Lifetime { kind: hir::LifetimeParamKind::Explicit }; @@ -3102,7 +3091,7 @@ impl<'hir> LoweringContext<'_, 'hir> { let hir_id = self.next_id(); if let Some(a) = attrs { assert!(!a.is_empty());- self.attrs.insert(hir_id.local_id, a);+ self.curr_owner.attrs.insert(hir_id.local_id, a); } let local = hir::LetStmt { super_: None,compiler/rustc_ast_lowering/src/pat.rs4 + / 4 −
@@ -289,17 +289,17 @@ impl<'hir> LoweringContext<'_, 'hir> { // will be resolved to the same `Res::Local`. Thus they just share a single // `HirId`. if id == p.id {- self.ident_and_label_to_local_id.insert(id, hir_id.local_id);+ self.curr_owner.ident_and_label_to_local_id.insert(id, hir_id.local_id); hir_id } else { hir::HirId {- owner: self.current_hir_id_owner,- local_id: self.ident_and_label_to_local_id[&id],+ owner: self.curr_owner.owner_id,+ local_id: self.curr_owner.ident_and_label_to_local_id[&id], } } } _ => {- self.ident_and_label_to_local_id.insert(p.id, hir_id.local_id);+ self.curr_owner.ident_and_label_to_local_id.insert(p.id, hir_id.local_id); hir_id } };compiler/rustc_ast_lowering/src/path.rs1 + / 1 −
@@ -425,7 +425,7 @@ impl<'hir> LoweringContext<'_, 'hir> { segment_ident_span: Span, generic_args: &mut GenericArgsCtor<'hir>, ) {- let (start, end) = match self.owner.get_lifetime_res(segment_id) {+ let (start, end) = match self.curr_owner.owner.get_lifetime_res(segment_id) { Some(LifetimeRes::ElidedAnchor { start, end }) => (start, end), None => return, Some(res) => {compiler/rustc_middle/src/ty/mod.rs4 + / 3 −
@@ -210,8 +210,8 @@ pub struct PerOwnerResolverData<'tcx> { pub node_id_to_def_id: NodeMap<LocalDefId> = 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.+ /// 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<ast::NodeId> = Default::default(), /// Resolutions for lifetimes. pub lifetimes_res_map: NodeMap<LifetimeRes> = Default::default(),@@ -221,7 +221,8 @@ pub struct PerOwnerResolverData<'tcx> { /// Resolution for import nodes, which have multiple resolutions in different namespaces. pub import_res: hir::def::PerNS<Option<Res<ast::NodeId>>> = Default::default(), /// Lifetime parameters that lowering will have to introduce.- pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, hir::MissingLifetimeKind)>> = Default::default(),+ pub extra_lifetime_params_map: NodeMap<Vec<(Ident, ast::NodeId, hir::MissingLifetimeKind)>> =+ Default::default(), /// The id of the owner pub id: ast::NodeId,