From a0bcce4884683cd3cb968f6cf6dd0d7720e9a6db Mon Sep 17 00:00:00 2001 From: Camille GILLOT Date: Wed, 22 Sep 2021 19:28:20 +0200 Subject: [PATCH 1/4] Store def_id_to_hir_id as variant in hir_owner. If hir_owner is Owner(_), the LocalDefId is pointing to an owner, so the ItemLocalId is 0. If the HIR node does not exist, we store Phantom. Otherwise, we store the HirId associated to the LocalDefId. --- compiler/rustc_ast_lowering/src/item.rs | 17 +++-- compiler/rustc_ast_lowering/src/lib.rs | 29 +++----- compiler/rustc_hir/src/definitions.rs | 31 +-------- compiler/rustc_hir/src/hir.rs | 48 +++++++++++-- compiler/rustc_hir/src/hir_id.rs | 5 ++ compiler/rustc_middle/src/hir/map/mod.rs | 69 ++++++++++--------- compiler/rustc_middle/src/hir/mod.rs | 18 ++--- compiler/rustc_middle/src/query/mod.rs | 4 +- compiler/rustc_middle/src/ty/context.rs | 2 - .../rustc_mir_transform/src/coverage/mod.rs | 2 +- compiler/rustc_resolve/src/late/lifetimes.rs | 10 +-- 11 files changed, 123 insertions(+), 112 deletions(-) diff --git a/compiler/rustc_ast_lowering/src/item.rs b/compiler/rustc_ast_lowering/src/item.rs index ed3abbd5b4d3d..8b4a0840df583 100644 --- a/compiler/rustc_ast_lowering/src/item.rs +++ b/compiler/rustc_ast_lowering/src/item.rs @@ -105,12 +105,11 @@ impl<'hir> LoweringContext<'_, 'hir> { ) -> T { let old_len = self.in_scope_lifetimes.len(); - let parent_generics = - match self.owners[parent_hir_id].as_ref().unwrap().node().expect_item().kind { - hir::ItemKind::Impl(hir::Impl { ref generics, .. }) - | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params, - _ => &[], - }; + let parent_generics = match self.owners[parent_hir_id].unwrap().node().expect_item().kind { + hir::ItemKind::Impl(hir::Impl { ref generics, .. }) + | hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params, + _ => &[], + }; let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind { hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()), _ => None, @@ -480,6 +479,12 @@ impl<'hir> LoweringContext<'_, 'hir> { .node_id_to_hir_id .insert(new_node_id, hir::HirId::make_owner(new_id)); debug_assert!(_old.is_none()); + self.owners.ensure_contains_elem(new_id, || hir::MaybeOwner::Phantom); + let _old = std::mem::replace( + &mut self.owners[new_id], + hir::MaybeOwner::NonOwner(hir::HirId::make_owner(new_id)), + ); + debug_assert!(matches!(_old, hir::MaybeOwner::Phantom)); continue; }; let ident = *ident; diff --git a/compiler/rustc_ast_lowering/src/lib.rs b/compiler/rustc_ast_lowering/src/lib.rs index 32cec3a295a4e..f21f0b895adb6 100644 --- a/compiler/rustc_ast_lowering/src/lib.rs +++ b/compiler/rustc_ast_lowering/src/lib.rs @@ -98,7 +98,7 @@ struct LoweringContext<'a, 'hir: 'a> { arena: &'hir Arena<'hir>, /// The items being lowered are collected here. - owners: IndexVec>>, + owners: IndexVec>>, /// Bodies inside the owner being lowered. bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>, /// Attributes inside the owner being lowered. @@ -291,7 +291,8 @@ pub fn lower_crate<'a, 'hir>( ) -> &'hir hir::Crate<'hir> { let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering"); - let owners = IndexVec::from_fn_n(|_| None, resolver.definitions().def_index_count()); + let owners = + IndexVec::from_fn_n(|_| hir::MaybeOwner::Phantom, resolver.definitions().def_index_count()); LoweringContext { sess, resolver, @@ -402,19 +403,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { let hir_hash = self.compute_hir_hash(); - let mut def_id_to_hir_id = IndexVec::default(); - - for (node_id, hir_id) in self.node_id_to_hir_id.into_iter_enumerated() { - if let Some(def_id) = self.resolver.opt_local_def_id(node_id) { - if def_id_to_hir_id.len() <= def_id.index() { - def_id_to_hir_id.resize(def_id.index() + 1, None); - } - def_id_to_hir_id[def_id] = hir_id; - } - } - - self.resolver.definitions().init_def_id_to_hir_id_mapping(def_id_to_hir_id); - let krate = hir::Crate { owners: self.owners, hir_hash }; self.arena.alloc(krate) } @@ -427,7 +415,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { .owners .iter_enumerated() .filter_map(|(def_id, info)| { - let info = info.as_ref()?; + let info = info.as_owner()?; let def_path_hash = definitions.def_path_hash(def_id); Some((def_path_hash, info)) }) @@ -469,8 +457,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { self.current_hir_id_owner = current_owner; self.item_local_id_counter = current_local_counter; - let _old = self.owners.insert(def_id, info); - debug_assert!(_old.is_none()); + self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); + self.owners[def_id] = hir::MaybeOwner::Owner(self.arena.alloc(info)); def_id } @@ -488,6 +476,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> { None } else { let def_id = self.resolver.opt_local_def_id(node_id)?; + self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom); + if let o @ hir::MaybeOwner::Phantom = &mut self.owners[def_id] { + // Do not override a `MaybeOwner::Owner` that may already here. + *o = hir::MaybeOwner::NonOwner(hir_id); + } Some((hir_id.local_id, def_id)) } }) diff --git a/compiler/rustc_hir/src/definitions.rs b/compiler/rustc_hir/src/definitions.rs index 74d6b05ca5fc5..d655f12f5e1d1 100644 --- a/compiler/rustc_hir/src/definitions.rs +++ b/compiler/rustc_hir/src/definitions.rs @@ -7,7 +7,6 @@ pub use crate::def_id::DefPathHash; use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE}; use crate::def_path_hash_map::DefPathHashMap; -use crate::hir; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::stable_hasher::StableHasher; @@ -101,13 +100,6 @@ impl DefPathTable { pub struct Definitions { table: DefPathTable, - /// Only [`LocalDefId`]s for items and item-like are HIR owners. - /// The associated `HirId` has a `local_id` of `0`. - /// Generic parameters and closures are also assigned a `LocalDefId` but are not HIR owners. - /// Their `HirId`s are defined by their position while lowering the enclosing owner. - // FIXME(cjgillot) Some `LocalDefId`s from `use` items are dropped during lowering and lack a `HirId`. - pub(super) def_id_to_hir_id: IndexVec>, - /// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`. expansions_that_defined: FxHashMap, @@ -322,12 +314,6 @@ impl Definitions { }) } - #[inline] - #[track_caller] - pub fn local_def_id_to_hir_id(&self, id: LocalDefId) -> hir::HirId { - self.def_id_to_hir_id[id].unwrap() - } - /// Adds a root definition (no parent) and a few other reserved definitions. pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions { let key = DefKey { @@ -354,7 +340,6 @@ impl Definitions { Definitions { table, - def_id_to_hir_id: Default::default(), expansions_that_defined: Default::default(), def_id_to_span, stable_crate_id, @@ -406,20 +391,6 @@ impl Definitions { def_id } - /// Initializes the `LocalDefId` to `HirId` mapping once it has been generated during - /// AST to HIR lowering. - pub fn init_def_id_to_hir_id_mapping( - &mut self, - mapping: IndexVec>, - ) { - assert!( - self.def_id_to_hir_id.is_empty(), - "trying to initialize `LocalDefId` <-> `HirId` mappings twice" - ); - - self.def_id_to_hir_id = mapping; - } - pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId { self.expansions_that_defined.get(&id).copied().unwrap_or_else(ExpnId::root) } @@ -431,7 +402,7 @@ impl Definitions { } pub fn iter_local_def_id(&self) -> impl Iterator + '_ { - self.def_id_to_hir_id.iter_enumerated().map(|(k, _)| k) + self.table.def_path_hashes.indices().map(|local_def_index| LocalDefId { local_def_index }) } #[inline(always)] diff --git a/compiler/rustc_hir/src/hir.rs b/compiler/rustc_hir/src/hir.rs index a0ed72c9e9e50..67398c80f360c 100644 --- a/compiler/rustc_hir/src/hir.rs +++ b/compiler/rustc_hir/src/hir.rs @@ -711,6 +711,15 @@ pub struct OwnerNodes<'tcx> { pub local_id_to_def_id: SortedMap, } +impl<'tcx> OwnerNodes<'tcx> { + pub fn node(&self) -> OwnerNode<'tcx> { + use rustc_index::vec::Idx; + let node = self.nodes[ItemLocalId::new(0)].as_ref().unwrap().node; + let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode. + node + } +} + /// Full information resulting from lowering an AST node. #[derive(Debug, HashStable_Generic)] pub struct OwnerInfo<'hir> { @@ -728,10 +737,39 @@ pub struct OwnerInfo<'hir> { impl<'tcx> OwnerInfo<'tcx> { #[inline] pub fn node(&self) -> OwnerNode<'tcx> { - use rustc_index::vec::Idx; - let node = self.nodes.nodes[ItemLocalId::new(0)].as_ref().unwrap().node; - let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode. - node + self.nodes.node() + } +} + +#[derive(Copy, Clone, Debug, HashStable_Generic)] +pub enum MaybeOwner { + Owner(T), + NonOwner(HirId), + /// Used as a placeholder for unused LocalDefId. + Phantom, +} + +impl MaybeOwner { + pub fn as_owner(self) -> Option { + match self { + MaybeOwner::Owner(i) => Some(i), + MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None, + } + } + + pub fn map(self, f: impl FnOnce(T) -> U) -> MaybeOwner { + match self { + MaybeOwner::Owner(i) => MaybeOwner::Owner(f(i)), + MaybeOwner::NonOwner(hir_id) => MaybeOwner::NonOwner(hir_id), + MaybeOwner::Phantom => MaybeOwner::Phantom, + } + } + + pub fn unwrap(self) -> T { + match self { + MaybeOwner::Owner(i) => i, + MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => panic!("Not a HIR owner"), + } } } @@ -743,7 +781,7 @@ impl<'tcx> OwnerInfo<'tcx> { /// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html #[derive(Debug)] pub struct Crate<'hir> { - pub owners: IndexVec>>, + pub owners: IndexVec>>, pub hir_hash: Fingerprint, } diff --git a/compiler/rustc_hir/src/hir_id.rs b/compiler/rustc_hir/src/hir_id.rs index 5b486819c35e8..dee391b9cce21 100644 --- a/compiler/rustc_hir/src/hir_id.rs +++ b/compiler/rustc_hir/src/hir_id.rs @@ -30,6 +30,11 @@ impl HirId { if self.local_id.index() == 0 { Some(self.owner) } else { None } } + #[inline] + pub fn is_owner(self) -> bool { + self.local_id.index() == 0 + } + #[inline] pub fn make_owner(owner: LocalDefId) -> Self { Self { owner, local_id: ItemLocalId::from_u32(0) } diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index 1885df6ac5d96..e75c16337ee4c 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -123,7 +123,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> { fn next(&mut self) -> Option { if self.current_id.local_id.index() != 0 { self.current_id.local_id = ItemLocalId::new(0); - if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) { + if let MaybeOwner::Owner(node) = self.map.tcx.hir_owner(self.current_id.owner) { return Some((self.current_id.owner, node.node)); } } @@ -141,7 +141,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> { self.current_id = HirId::make_owner(parent_id); // If this `HirId` doesn't have an entry, skip it and look for its `parent_id`. - if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) { + if let MaybeOwner::Owner(node) = self.map.tcx.hir_owner(self.current_id.owner) { return Some((self.current_id.owner, node.node)); } } @@ -155,14 +155,14 @@ impl<'hir> Map<'hir> { pub fn root_module(&self) -> &'hir Mod<'hir> { match self.tcx.hir_owner(CRATE_DEF_ID).map(|o| o.node) { - Some(OwnerNode::Crate(item)) => item, + MaybeOwner::Owner(OwnerNode::Crate(item)) => item, _ => bug!(), } } pub fn items(&self) -> impl Iterator> + 'hir { let krate = self.krate(); - krate.owners.iter().filter_map(|owner| match owner.as_ref()?.node() { + krate.owners.iter().filter_map(|owner| match owner.as_owner()?.node() { OwnerNode::Item(item) => Some(item), _ => None, }) @@ -205,7 +205,8 @@ impl<'hir> Map<'hir> { Some(hir_id.owner) } else { self.tcx - .hir_owner_nodes(hir_id.owner)? + .hir_owner_nodes(hir_id.owner) + .as_owner()? .local_id_to_def_id .get(&hir_id.local_id) .copied() @@ -214,8 +215,12 @@ impl<'hir> Map<'hir> { #[inline] pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId { - // FIXME(#85914) is this access safe for incr. comp.? - self.tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id) + let owner = self.tcx.hir_owner(def_id); + match owner { + MaybeOwner::Owner(_) => HirId::make_owner(def_id), + MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id), + MaybeOwner::NonOwner(hir_id) => hir_id, + } } pub fn iter_local_def_id(&self) -> impl Iterator + '_ { @@ -321,7 +326,7 @@ impl<'hir> Map<'hir> { if id.local_id == ItemLocalId::from_u32(0) { Some(self.tcx.hir_owner_parent(id.owner)) } else { - let owner = self.tcx.hir_owner_nodes(id.owner)?; + let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?; let node = owner.nodes[id.local_id].as_ref()?; let hir_id = HirId { owner: id.owner, local_id: node.parent }; Some(hir_id) @@ -335,10 +340,10 @@ impl<'hir> Map<'hir> { /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. pub fn find(&self, id: HirId) -> Option> { if id.local_id == ItemLocalId::from_u32(0) { - let owner = self.tcx.hir_owner(id.owner)?; + let owner = self.tcx.hir_owner(id.owner).as_owner()?; Some(owner.node.into()) } else { - let owner = self.tcx.hir_owner_nodes(id.owner)?; + let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?; let node = owner.nodes[id.local_id].as_ref()?; Some(node.node) } @@ -366,7 +371,7 @@ impl<'hir> Map<'hir> { } pub fn get_generics(&self, id: LocalDefId) -> Option<&'hir Generics<'hir>> { - let node = self.tcx.hir_owner(id)?; + let node = self.tcx.hir_owner(id).as_owner()?; match node.node { OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics), OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics), @@ -522,7 +527,7 @@ impl<'hir> Map<'hir> { .owners .iter_enumerated() .flat_map(move |(owner, owner_info)| { - let bodies = &owner_info.as_ref()?.nodes.bodies; + let bodies = &owner_info.as_owner()?.nodes.bodies; Some(bodies.iter().map(move |&(local_id, _)| { let hir_id = HirId { owner, local_id }; let body_id = BodyId { hir_id }; @@ -539,7 +544,7 @@ impl<'hir> Map<'hir> { par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| { let owner = LocalDefId::new(owner); - if let Some(owner_info) = owner_info { + if let MaybeOwner::Owner(owner_info) = owner_info { par_iter(owner_info.nodes.bodies.range(..)).for_each(|(local_id, _)| { let hir_id = HirId { owner, local_id: *local_id }; let body_id = BodyId { hir_id }; @@ -583,10 +588,10 @@ impl<'hir> Map<'hir> { pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) { let hir_id = HirId::make_owner(module); match self.tcx.hir_owner(module).map(|o| o.node) { - Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => { - (m, span, hir_id) - } - Some(OwnerNode::Crate(item)) => (item, item.inner, hir_id), + MaybeOwner::Owner(OwnerNode::Item(&Item { + span, kind: ItemKind::Mod(ref m), .. + })) => (m, span, hir_id), + MaybeOwner::Owner(OwnerNode::Crate(item)) => (item, item.inner, hir_id), node => panic!("not a module: {:?}", node), } } @@ -601,7 +606,7 @@ impl<'hir> Map<'hir> { pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) { let krate = self.krate(); for (owner, info) in krate.owners.iter_enumerated() { - if let Some(info) = info { + if let MaybeOwner::Owner(info) = info { for (local_id, attrs) in info.attrs.map.iter() { let id = HirId { owner, local_id: *local_id }; for a in *attrs { @@ -625,7 +630,7 @@ impl<'hir> Map<'hir> { V: itemlikevisit::ItemLikeVisitor<'hir>, { let krate = self.krate(); - for owner in krate.owners.iter().filter_map(Option::as_ref) { + for owner in krate.owners.iter().filter_map(|i| i.as_owner()) { match owner.node() { OwnerNode::Item(item) => visitor.visit_item(item), OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item), @@ -642,12 +647,14 @@ impl<'hir> Map<'hir> { V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send, { let krate = self.krate(); - par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref().map(OwnerInfo::node) { - Some(OwnerNode::Item(item)) => visitor.visit_item(item), - Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item), - Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item), - Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item), - Some(OwnerNode::Crate(_)) | None => {} + par_for_each_in(&krate.owners.raw, |owner| match owner.map(OwnerInfo::node) { + MaybeOwner::Owner(OwnerNode::Item(item)) => visitor.visit_item(item), + MaybeOwner::Owner(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item), + MaybeOwner::Owner(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item), + MaybeOwner::Owner(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item), + MaybeOwner::Owner(OwnerNode::Crate(_)) + | MaybeOwner::NonOwner(_) + | MaybeOwner::Phantom => {} }) } @@ -878,7 +885,7 @@ impl<'hir> Map<'hir> { pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi { let parent = self.get_parent_item(hir_id); - if let Some(node) = self.tcx.hir_owner(parent) { + if let MaybeOwner::Owner(node) = self.tcx.hir_owner(parent) { if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node.node { return *abi; @@ -892,21 +899,21 @@ impl<'hir> Map<'hir> { pub fn expect_item(&self, id: LocalDefId) -> &'hir Item<'hir> { match self.tcx.hir_owner(id) { - Some(Owner { node: OwnerNode::Item(item), .. }) => item, + MaybeOwner::Owner(Owner { node: OwnerNode::Item(item), .. }) => item, _ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))), } } pub fn expect_impl_item(&self, id: LocalDefId) -> &'hir ImplItem<'hir> { match self.tcx.hir_owner(id) { - Some(Owner { node: OwnerNode::ImplItem(item), .. }) => item, + MaybeOwner::Owner(Owner { node: OwnerNode::ImplItem(item), .. }) => item, _ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))), } } pub fn expect_trait_item(&self, id: LocalDefId) -> &'hir TraitItem<'hir> { match self.tcx.hir_owner(id) { - Some(Owner { node: OwnerNode::TraitItem(item), .. }) => item, + MaybeOwner::Owner(Owner { node: OwnerNode::TraitItem(item), .. }) => item, _ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))), } } @@ -920,7 +927,7 @@ impl<'hir> Map<'hir> { pub fn expect_foreign_item(&self, id: LocalDefId) -> &'hir ForeignItem<'hir> { match self.tcx.hir_owner(id) { - Some(Owner { node: OwnerNode::ForeignItem(item), .. }) => item, + MaybeOwner::Owner(Owner { node: OwnerNode::ForeignItem(item), .. }) => item, _ => { bug!("expected foreign item, found {}", self.node_to_string(HirId::make_owner(id))) } @@ -1121,7 +1128,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh { .owners .iter_enumerated() .filter_map(|(def_id, info)| { - let _ = info.as_ref()?; + let _ = info.as_owner()?; let def_path_hash = definitions.def_path_hash(def_id); let span = definitions.def_span(def_id); debug_assert_eq!(span.parent(), None); diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index b4c7bb7eba79c..5543e96036b51 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -65,20 +65,20 @@ pub fn provide(providers: &mut Providers) { providers.crate_hash = map::crate_hash; providers.hir_module_items = map::hir_module_items; providers.hir_owner = |tcx, id| { - let owner = tcx.hir_crate(()).owners.get(id)?.as_ref()?; - let node = owner.node(); - Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }) + tcx.hir_crate(()).owners[id].map(|owner| { + let node = owner.nodes.node(); + Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies } + }) }; - providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|i| &i.nodes); + providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id].map(|i| &i.nodes); providers.hir_owner_parent = |tcx, id| { // Accessing the def_key is ok since its value is hashed as part of `id`'s DefPathHash. let parent = tcx.untracked_resolutions.definitions.def_key(id).parent; let parent = parent.map_or(CRATE_HIR_ID, |local_def_index| { let def_id = LocalDefId { local_def_index }; - let mut parent_hir_id = - tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id); + let mut parent_hir_id = tcx.hir().local_def_id_to_hir_id(def_id); if let Some(local_id) = - tcx.hir_crate(()).owners[parent_hir_id.owner].as_ref().unwrap().parenting.get(&id) + tcx.hir_crate(()).owners[parent_hir_id.owner].unwrap().parenting.get(&id) { parent_hir_id.local_id = *local_id; } @@ -87,7 +87,7 @@ pub fn provide(providers: &mut Providers) { parent }; providers.hir_attrs = - |tcx, id| tcx.hir_crate(()).owners[id].as_ref().map_or(AttributeMap::EMPTY, |o| &o.attrs); + |tcx, id| tcx.hir_crate(()).owners[id].as_owner().map_or(AttributeMap::EMPTY, |o| &o.attrs); providers.source_span = |tcx, def_id| tcx.resolutions(()).definitions.def_span(def_id); providers.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP); providers.fn_arg_names = |tcx, id| { @@ -111,4 +111,6 @@ pub fn provide(providers: &mut Providers) { let id = id.expect_local(); tcx.resolutions(()).definitions.expansion_that_defined(id) }; + providers.in_scope_traits_map = + |tcx, id| tcx.hir_crate(()).owners[id].as_owner().map(|owner_info| &owner_info.trait_map); } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 715a1fa25a1c6..f5b4925fbb3e6 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -52,7 +52,7 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query hir_owner(key: LocalDefId) -> Option> { + query hir_owner(key: LocalDefId) -> hir::MaybeOwner> { desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) } } @@ -68,7 +68,7 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query hir_owner_nodes(key: LocalDefId) -> Option<&'tcx hir::OwnerNodes<'tcx>> { + query hir_owner_nodes(key: LocalDefId) -> hir::MaybeOwner<&'tcx hir::OwnerNodes<'tcx>> { desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) } } diff --git a/compiler/rustc_middle/src/ty/context.rs b/compiler/rustc_middle/src/ty/context.rs index 6c8573805cb94..75f1318e36314 100644 --- a/compiler/rustc_middle/src/ty/context.rs +++ b/compiler/rustc_middle/src/ty/context.rs @@ -2875,8 +2875,6 @@ fn ptr_eq(t: *const T, u: *const U) -> bool { } pub fn provide(providers: &mut ty::query::Providers) { - providers.in_scope_traits_map = - |tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|owner_info| &owner_info.trait_map); providers.resolutions = |tcx, ()| &tcx.untracked_resolutions; providers.module_reexports = |tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]); diff --git a/compiler/rustc_mir_transform/src/coverage/mod.rs b/compiler/rustc_mir_transform/src/coverage/mod.rs index 82455654a8860..2bb9f48f9b7c8 100644 --- a/compiler/rustc_mir_transform/src/coverage/mod.rs +++ b/compiler/rustc_mir_transform/src/coverage/mod.rs @@ -579,7 +579,7 @@ fn hash_mir_source<'tcx>(tcx: TyCtxt<'tcx>, hir_body: &'tcx rustc_hir::Body<'tcx let mut hcx = tcx.create_no_span_stable_hashing_context(); let mut stable_hasher = StableHasher::new(); let owner = hir_body.id().hir_id.owner; - let bodies = &tcx.hir_owner_nodes(owner).as_ref().unwrap().bodies; + let bodies = &tcx.hir_owner_nodes(owner).unwrap().bodies; hcx.with_hir_bodies(false, owner, bodies, |hcx| { hir_body.value.hash_stable(hcx, &mut stable_hasher) }); diff --git a/compiler/rustc_resolve/src/late/lifetimes.rs b/compiler/rustc_resolve/src/late/lifetimes.rs index 4c7bdb33fb87a..6ef85c426be70 100644 --- a/compiler/rustc_resolve/src/late/lifetimes.rs +++ b/compiler/rustc_resolve/src/late/lifetimes.rs @@ -1019,15 +1019,7 @@ impl<'a, 'tcx> Visitor<'tcx> for LifetimeContext<'a, 'tcx> { let hir_id = self.tcx.hir().local_def_id_to_hir_id(def_id); // Ensure that the parent of the def is an item, not HRTB let parent_id = self.tcx.hir().get_parent_node(hir_id); - // FIXME(cjgillot) Can this check be replaced by - // `let parent_is_item = parent_id.is_owner();`? - let parent_is_item = if let Some(parent_def_id) = parent_id.as_owner() { - matches!(self.tcx.hir().krate().owners.get(parent_def_id), Some(Some(_)),) - } else { - false - }; - - if !parent_is_item { + if !parent_id.is_owner() { if !self.trait_definition_only { struct_span_err!( self.tcx.sess, From d17eb78cf836610d8571806744785f1cbcbb6481 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 28 Jan 2022 14:58:27 -0300 Subject: [PATCH 2/4] Separate hir_owner query into two queries to avoid using extensive data on incr comp most of the time --- compiler/rustc_middle/src/hir/map/mod.rs | 30 ++++++++++++------------ compiler/rustc_middle/src/hir/mod.rs | 5 ++++ compiler/rustc_middle/src/query/mod.rs | 10 +++++++- 3 files changed, 29 insertions(+), 16 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index e75c16337ee4c..a83f027595dce 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -123,7 +123,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> { fn next(&mut self) -> Option { if self.current_id.local_id.index() != 0 { self.current_id.local_id = ItemLocalId::new(0); - if let MaybeOwner::Owner(node) = self.map.tcx.hir_owner(self.current_id.owner) { + if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) { return Some((self.current_id.owner, node.node)); } } @@ -141,7 +141,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> { self.current_id = HirId::make_owner(parent_id); // If this `HirId` doesn't have an entry, skip it and look for its `parent_id`. - if let MaybeOwner::Owner(node) = self.map.tcx.hir_owner(self.current_id.owner) { + if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) { return Some((self.current_id.owner, node.node)); } } @@ -155,7 +155,7 @@ impl<'hir> Map<'hir> { pub fn root_module(&self) -> &'hir Mod<'hir> { match self.tcx.hir_owner(CRATE_DEF_ID).map(|o| o.node) { - MaybeOwner::Owner(OwnerNode::Crate(item)) => item, + Some(OwnerNode::Crate(item)) => item, _ => bug!(), } } @@ -215,7 +215,7 @@ impl<'hir> Map<'hir> { #[inline] pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId { - let owner = self.tcx.hir_owner(def_id); + let owner = self.tcx.local_def_id_to_hir_id(def_id); match owner { MaybeOwner::Owner(_) => HirId::make_owner(def_id), MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id), @@ -340,7 +340,7 @@ impl<'hir> Map<'hir> { /// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found. pub fn find(&self, id: HirId) -> Option> { if id.local_id == ItemLocalId::from_u32(0) { - let owner = self.tcx.hir_owner(id.owner).as_owner()?; + let owner = self.tcx.hir_owner(id.owner)?; Some(owner.node.into()) } else { let owner = self.tcx.hir_owner_nodes(id.owner).as_owner()?; @@ -371,7 +371,7 @@ impl<'hir> Map<'hir> { } pub fn get_generics(&self, id: LocalDefId) -> Option<&'hir Generics<'hir>> { - let node = self.tcx.hir_owner(id).as_owner()?; + let node = self.tcx.hir_owner(id)?; match node.node { OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics), OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics), @@ -588,10 +588,10 @@ impl<'hir> Map<'hir> { pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) { let hir_id = HirId::make_owner(module); match self.tcx.hir_owner(module).map(|o| o.node) { - MaybeOwner::Owner(OwnerNode::Item(&Item { - span, kind: ItemKind::Mod(ref m), .. - })) => (m, span, hir_id), - MaybeOwner::Owner(OwnerNode::Crate(item)) => (item, item.inner, hir_id), + Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => { + (m, span, hir_id) + } + Some(OwnerNode::Crate(item)) => (item, item.inner, hir_id), node => panic!("not a module: {:?}", node), } } @@ -885,7 +885,7 @@ impl<'hir> Map<'hir> { pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi { let parent = self.get_parent_item(hir_id); - if let MaybeOwner::Owner(node) = self.tcx.hir_owner(parent) { + if let Some(node) = self.tcx.hir_owner(parent) { if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node.node { return *abi; @@ -899,21 +899,21 @@ impl<'hir> Map<'hir> { pub fn expect_item(&self, id: LocalDefId) -> &'hir Item<'hir> { match self.tcx.hir_owner(id) { - MaybeOwner::Owner(Owner { node: OwnerNode::Item(item), .. }) => item, + Some(Owner { node: OwnerNode::Item(item), .. }) => item, _ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))), } } pub fn expect_impl_item(&self, id: LocalDefId) -> &'hir ImplItem<'hir> { match self.tcx.hir_owner(id) { - MaybeOwner::Owner(Owner { node: OwnerNode::ImplItem(item), .. }) => item, + Some(Owner { node: OwnerNode::ImplItem(item), .. }) => item, _ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))), } } pub fn expect_trait_item(&self, id: LocalDefId) -> &'hir TraitItem<'hir> { match self.tcx.hir_owner(id) { - MaybeOwner::Owner(Owner { node: OwnerNode::TraitItem(item), .. }) => item, + Some(Owner { node: OwnerNode::TraitItem(item), .. }) => item, _ => bug!("expected trait item, found {}", self.node_to_string(HirId::make_owner(id))), } } @@ -927,7 +927,7 @@ impl<'hir> Map<'hir> { pub fn expect_foreign_item(&self, id: LocalDefId) -> &'hir ForeignItem<'hir> { match self.tcx.hir_owner(id) { - MaybeOwner::Owner(Owner { node: OwnerNode::ForeignItem(item), .. }) => item, + Some(Owner { node: OwnerNode::ForeignItem(item), .. }) => item, _ => { bug!("expected foreign item, found {}", self.node_to_string(HirId::make_owner(id))) } diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 5543e96036b51..16b41c8f9d1b4 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -65,6 +65,11 @@ pub fn provide(providers: &mut Providers) { providers.crate_hash = map::crate_hash; providers.hir_module_items = map::hir_module_items; providers.hir_owner = |tcx, id| { + let owner = tcx.hir_crate(()).owners.get(id)?.as_owner()?; + let node = owner.node(); + Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }) + }; + providers.local_def_id_to_hir_id = |tcx, id| { tcx.hir_crate(()).owners[id].map(|owner| { let node = owner.nodes.node(); Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies } diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index f5b4925fbb3e6..2eadcc6c1d3f9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -52,10 +52,18 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query hir_owner(key: LocalDefId) -> hir::MaybeOwner> { + query hir_owner(key: LocalDefId) -> Option> { desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) } } + /// Gives access to the HIR ID for the given `LocalDefId` owner `key`. + /// + /// This can be conveniently accessed by methods on `tcx.hir()`. + /// Avoid calling this query directly. + query local_def_id_to_hir_id(key: LocalDefId) -> hir::MaybeOwner> { + desc { |tcx| "HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } + } + /// Gives access to the HIR node's parent for the HIR owner `key`. /// /// This can be conveniently accessed by methods on `tcx.hir()`. From 5a299a9903abd6bd5161d610855b0c123ed58dfb Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Fri, 28 Jan 2022 15:13:01 -0300 Subject: [PATCH 3/4] Make local_def_id_to_hir_id return MaybeOwner<()> --- compiler/rustc_middle/src/hir/mod.rs | 7 +------ compiler/rustc_middle/src/query/mod.rs | 2 +- 2 files changed, 2 insertions(+), 7 deletions(-) diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 16b41c8f9d1b4..12379eed80ec4 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -69,12 +69,7 @@ pub fn provide(providers: &mut Providers) { let node = owner.node(); Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }) }; - providers.local_def_id_to_hir_id = |tcx, id| { - tcx.hir_crate(()).owners[id].map(|owner| { - let node = owner.nodes.node(); - Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies } - }) - }; + providers.local_def_id_to_hir_id = |tcx, id| tcx.hir_crate(()).owners[id].map(|_| ()); providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id].map(|i| &i.nodes); providers.hir_owner_parent = |tcx, id| { // Accessing the def_key is ok since its value is hashed as part of `id`'s DefPathHash. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 2eadcc6c1d3f9..334e06aa685a9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -60,7 +60,7 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query local_def_id_to_hir_id(key: LocalDefId) -> hir::MaybeOwner> { + query local_def_id_to_hir_id(key: LocalDefId) -> hir::MaybeOwner<()> { desc { |tcx| "HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } } From bf1ca2e4b01b9930d29064b1d170a9ead0415fa2 Mon Sep 17 00:00:00 2001 From: Santiago Pastorino Date: Sat, 29 Jan 2022 08:40:23 -0300 Subject: [PATCH 4/4] Make local_def_id_to_hir_id query directly returh HirId --- compiler/rustc_middle/src/hir/map/mod.rs | 7 +------ compiler/rustc_middle/src/hir/mod.rs | 9 ++++++++- compiler/rustc_middle/src/query/mod.rs | 2 +- 3 files changed, 10 insertions(+), 8 deletions(-) diff --git a/compiler/rustc_middle/src/hir/map/mod.rs b/compiler/rustc_middle/src/hir/map/mod.rs index a83f027595dce..649cb34bd5f3c 100644 --- a/compiler/rustc_middle/src/hir/map/mod.rs +++ b/compiler/rustc_middle/src/hir/map/mod.rs @@ -215,12 +215,7 @@ impl<'hir> Map<'hir> { #[inline] pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId { - let owner = self.tcx.local_def_id_to_hir_id(def_id); - match owner { - MaybeOwner::Owner(_) => HirId::make_owner(def_id), - MaybeOwner::Phantom => bug!("No HirId for {:?}", def_id), - MaybeOwner::NonOwner(hir_id) => hir_id, - } + self.tcx.local_def_id_to_hir_id(def_id) } pub fn iter_local_def_id(&self) -> impl Iterator + '_ { diff --git a/compiler/rustc_middle/src/hir/mod.rs b/compiler/rustc_middle/src/hir/mod.rs index 12379eed80ec4..1053f0cefbedd 100644 --- a/compiler/rustc_middle/src/hir/mod.rs +++ b/compiler/rustc_middle/src/hir/mod.rs @@ -69,7 +69,14 @@ pub fn provide(providers: &mut Providers) { let node = owner.node(); Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies }) }; - providers.local_def_id_to_hir_id = |tcx, id| tcx.hir_crate(()).owners[id].map(|_| ()); + providers.local_def_id_to_hir_id = |tcx, id| { + let owner = tcx.hir_crate(()).owners[id].map(|_| ()); + match owner { + MaybeOwner::Owner(_) => HirId::make_owner(id), + MaybeOwner::Phantom => bug!("No HirId for {:?}", id), + MaybeOwner::NonOwner(hir_id) => hir_id, + } + }; providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id].map(|i| &i.nodes); providers.hir_owner_parent = |tcx, id| { // Accessing the def_key is ok since its value is hashed as part of `id`'s DefPathHash. diff --git a/compiler/rustc_middle/src/query/mod.rs b/compiler/rustc_middle/src/query/mod.rs index 334e06aa685a9..c01e7177760f9 100644 --- a/compiler/rustc_middle/src/query/mod.rs +++ b/compiler/rustc_middle/src/query/mod.rs @@ -60,7 +60,7 @@ rustc_queries! { /// /// This can be conveniently accessed by methods on `tcx.hir()`. /// Avoid calling this query directly. - query local_def_id_to_hir_id(key: LocalDefId) -> hir::MaybeOwner<()> { + query local_def_id_to_hir_id(key: LocalDefId) -> hir::HirId { desc { |tcx| "HIR ID of `{}`", tcx.def_path_str(key.to_def_id()) } }