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.
This commit is contained in:
parent
009c1d0248
commit
a0bcce4884
11 changed files with 123 additions and 112 deletions
|
@ -105,12 +105,11 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
) -> T {
|
) -> T {
|
||||||
let old_len = self.in_scope_lifetimes.len();
|
let old_len = self.in_scope_lifetimes.len();
|
||||||
|
|
||||||
let parent_generics =
|
let parent_generics = match self.owners[parent_hir_id].unwrap().node().expect_item().kind {
|
||||||
match self.owners[parent_hir_id].as_ref().unwrap().node().expect_item().kind {
|
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
|
||||||
hir::ItemKind::Impl(hir::Impl { ref generics, .. })
|
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
|
||||||
| hir::ItemKind::Trait(_, _, ref generics, ..) => generics.params,
|
_ => &[],
|
||||||
_ => &[],
|
};
|
||||||
};
|
|
||||||
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
|
let lt_def_names = parent_generics.iter().filter_map(|param| match param.kind {
|
||||||
hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
|
hir::GenericParamKind::Lifetime { .. } => Some(param.name.normalize_to_macros_2_0()),
|
||||||
_ => None,
|
_ => None,
|
||||||
|
@ -480,6 +479,12 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
||||||
.node_id_to_hir_id
|
.node_id_to_hir_id
|
||||||
.insert(new_node_id, hir::HirId::make_owner(new_id));
|
.insert(new_node_id, hir::HirId::make_owner(new_id));
|
||||||
debug_assert!(_old.is_none());
|
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;
|
continue;
|
||||||
};
|
};
|
||||||
let ident = *ident;
|
let ident = *ident;
|
||||||
|
|
|
@ -98,7 +98,7 @@ struct LoweringContext<'a, 'hir: 'a> {
|
||||||
arena: &'hir Arena<'hir>,
|
arena: &'hir Arena<'hir>,
|
||||||
|
|
||||||
/// The items being lowered are collected here.
|
/// The items being lowered are collected here.
|
||||||
owners: IndexVec<LocalDefId, Option<hir::OwnerInfo<'hir>>>,
|
owners: IndexVec<LocalDefId, hir::MaybeOwner<&'hir hir::OwnerInfo<'hir>>>,
|
||||||
/// Bodies inside the owner being lowered.
|
/// Bodies inside the owner being lowered.
|
||||||
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
|
bodies: Vec<(hir::ItemLocalId, &'hir hir::Body<'hir>)>,
|
||||||
/// Attributes inside the owner being lowered.
|
/// Attributes inside the owner being lowered.
|
||||||
|
@ -291,7 +291,8 @@ pub fn lower_crate<'a, 'hir>(
|
||||||
) -> &'hir hir::Crate<'hir> {
|
) -> &'hir hir::Crate<'hir> {
|
||||||
let _prof_timer = sess.prof.verbose_generic_activity("hir_lowering");
|
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 {
|
LoweringContext {
|
||||||
sess,
|
sess,
|
||||||
resolver,
|
resolver,
|
||||||
|
@ -402,19 +403,6 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
|
|
||||||
let hir_hash = self.compute_hir_hash();
|
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 };
|
let krate = hir::Crate { owners: self.owners, hir_hash };
|
||||||
self.arena.alloc(krate)
|
self.arena.alloc(krate)
|
||||||
}
|
}
|
||||||
|
@ -427,7 +415,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
.owners
|
.owners
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.filter_map(|(def_id, info)| {
|
.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);
|
let def_path_hash = definitions.def_path_hash(def_id);
|
||||||
Some((def_path_hash, info))
|
Some((def_path_hash, info))
|
||||||
})
|
})
|
||||||
|
@ -469,8 +457,8 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
self.current_hir_id_owner = current_owner;
|
self.current_hir_id_owner = current_owner;
|
||||||
self.item_local_id_counter = current_local_counter;
|
self.item_local_id_counter = current_local_counter;
|
||||||
|
|
||||||
let _old = self.owners.insert(def_id, info);
|
self.owners.ensure_contains_elem(def_id, || hir::MaybeOwner::Phantom);
|
||||||
debug_assert!(_old.is_none());
|
self.owners[def_id] = hir::MaybeOwner::Owner(self.arena.alloc(info));
|
||||||
|
|
||||||
def_id
|
def_id
|
||||||
}
|
}
|
||||||
|
@ -488,6 +476,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
let def_id = self.resolver.opt_local_def_id(node_id)?;
|
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))
|
Some((hir_id.local_id, def_id))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
|
@ -7,7 +7,6 @@
|
||||||
pub use crate::def_id::DefPathHash;
|
pub use crate::def_id::DefPathHash;
|
||||||
use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
use crate::def_id::{CrateNum, DefIndex, LocalDefId, StableCrateId, CRATE_DEF_INDEX, LOCAL_CRATE};
|
||||||
use crate::def_path_hash_map::DefPathHashMap;
|
use crate::def_path_hash_map::DefPathHashMap;
|
||||||
use crate::hir;
|
|
||||||
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_data_structures::stable_hasher::StableHasher;
|
use rustc_data_structures::stable_hasher::StableHasher;
|
||||||
|
@ -101,13 +100,6 @@ impl DefPathTable {
|
||||||
pub struct Definitions {
|
pub struct Definitions {
|
||||||
table: DefPathTable,
|
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<LocalDefId, Option<hir::HirId>>,
|
|
||||||
|
|
||||||
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
|
/// Item with a given `LocalDefId` was defined during macro expansion with ID `ExpnId`.
|
||||||
expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,
|
expansions_that_defined: FxHashMap<LocalDefId, ExpnId>,
|
||||||
|
|
||||||
|
@ -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.
|
/// Adds a root definition (no parent) and a few other reserved definitions.
|
||||||
pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions {
|
pub fn new(stable_crate_id: StableCrateId, crate_span: Span) -> Definitions {
|
||||||
let key = DefKey {
|
let key = DefKey {
|
||||||
|
@ -354,7 +340,6 @@ impl Definitions {
|
||||||
|
|
||||||
Definitions {
|
Definitions {
|
||||||
table,
|
table,
|
||||||
def_id_to_hir_id: Default::default(),
|
|
||||||
expansions_that_defined: Default::default(),
|
expansions_that_defined: Default::default(),
|
||||||
def_id_to_span,
|
def_id_to_span,
|
||||||
stable_crate_id,
|
stable_crate_id,
|
||||||
|
@ -406,20 +391,6 @@ impl Definitions {
|
||||||
def_id
|
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<LocalDefId, Option<hir::HirId>>,
|
|
||||||
) {
|
|
||||||
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 {
|
pub fn expansion_that_defined(&self, id: LocalDefId) -> ExpnId {
|
||||||
self.expansions_that_defined.get(&id).copied().unwrap_or_else(ExpnId::root)
|
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<Item = LocalDefId> + '_ {
|
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
|
||||||
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)]
|
#[inline(always)]
|
||||||
|
|
|
@ -711,6 +711,15 @@ pub struct OwnerNodes<'tcx> {
|
||||||
pub local_id_to_def_id: SortedMap<ItemLocalId, LocalDefId>,
|
pub local_id_to_def_id: SortedMap<ItemLocalId, LocalDefId>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
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.
|
/// Full information resulting from lowering an AST node.
|
||||||
#[derive(Debug, HashStable_Generic)]
|
#[derive(Debug, HashStable_Generic)]
|
||||||
pub struct OwnerInfo<'hir> {
|
pub struct OwnerInfo<'hir> {
|
||||||
|
@ -728,10 +737,39 @@ pub struct OwnerInfo<'hir> {
|
||||||
impl<'tcx> OwnerInfo<'tcx> {
|
impl<'tcx> OwnerInfo<'tcx> {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn node(&self) -> OwnerNode<'tcx> {
|
pub fn node(&self) -> OwnerNode<'tcx> {
|
||||||
use rustc_index::vec::Idx;
|
self.nodes.node()
|
||||||
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
|
|
||||||
|
#[derive(Copy, Clone, Debug, HashStable_Generic)]
|
||||||
|
pub enum MaybeOwner<T> {
|
||||||
|
Owner(T),
|
||||||
|
NonOwner(HirId),
|
||||||
|
/// Used as a placeholder for unused LocalDefId.
|
||||||
|
Phantom,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<T> MaybeOwner<T> {
|
||||||
|
pub fn as_owner(self) -> Option<T> {
|
||||||
|
match self {
|
||||||
|
MaybeOwner::Owner(i) => Some(i),
|
||||||
|
MaybeOwner::NonOwner(_) | MaybeOwner::Phantom => None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn map<U>(self, f: impl FnOnce(T) -> U) -> MaybeOwner<U> {
|
||||||
|
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
|
/// [rustc dev guide]: https://rustc-dev-guide.rust-lang.org/hir.html
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Crate<'hir> {
|
pub struct Crate<'hir> {
|
||||||
pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
|
pub owners: IndexVec<LocalDefId, MaybeOwner<&'hir OwnerInfo<'hir>>>,
|
||||||
pub hir_hash: Fingerprint,
|
pub hir_hash: Fingerprint,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -30,6 +30,11 @@ impl HirId {
|
||||||
if self.local_id.index() == 0 { Some(self.owner) } else { None }
|
if self.local_id.index() == 0 { Some(self.owner) } else { None }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
pub fn is_owner(self) -> bool {
|
||||||
|
self.local_id.index() == 0
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn make_owner(owner: LocalDefId) -> Self {
|
pub fn make_owner(owner: LocalDefId) -> Self {
|
||||||
Self { owner, local_id: ItemLocalId::from_u32(0) }
|
Self { owner, local_id: ItemLocalId::from_u32(0) }
|
||||||
|
|
|
@ -123,7 +123,7 @@ impl<'hir> Iterator for ParentOwnerIterator<'hir> {
|
||||||
fn next(&mut self) -> Option<Self::Item> {
|
fn next(&mut self) -> Option<Self::Item> {
|
||||||
if self.current_id.local_id.index() != 0 {
|
if self.current_id.local_id.index() != 0 {
|
||||||
self.current_id.local_id = ItemLocalId::new(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));
|
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);
|
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 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));
|
return Some((self.current_id.owner, node.node));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -155,14 +155,14 @@ impl<'hir> Map<'hir> {
|
||||||
|
|
||||||
pub fn root_module(&self) -> &'hir Mod<'hir> {
|
pub fn root_module(&self) -> &'hir Mod<'hir> {
|
||||||
match self.tcx.hir_owner(CRATE_DEF_ID).map(|o| o.node) {
|
match self.tcx.hir_owner(CRATE_DEF_ID).map(|o| o.node) {
|
||||||
Some(OwnerNode::Crate(item)) => item,
|
MaybeOwner::Owner(OwnerNode::Crate(item)) => item,
|
||||||
_ => bug!(),
|
_ => bug!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
|
pub fn items(&self) -> impl Iterator<Item = &'hir Item<'hir>> + 'hir {
|
||||||
let krate = self.krate();
|
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),
|
OwnerNode::Item(item) => Some(item),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
|
@ -205,7 +205,8 @@ impl<'hir> Map<'hir> {
|
||||||
Some(hir_id.owner)
|
Some(hir_id.owner)
|
||||||
} else {
|
} else {
|
||||||
self.tcx
|
self.tcx
|
||||||
.hir_owner_nodes(hir_id.owner)?
|
.hir_owner_nodes(hir_id.owner)
|
||||||
|
.as_owner()?
|
||||||
.local_id_to_def_id
|
.local_id_to_def_id
|
||||||
.get(&hir_id.local_id)
|
.get(&hir_id.local_id)
|
||||||
.copied()
|
.copied()
|
||||||
|
@ -214,8 +215,12 @@ impl<'hir> Map<'hir> {
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
|
pub fn local_def_id_to_hir_id(&self, def_id: LocalDefId) -> HirId {
|
||||||
// FIXME(#85914) is this access safe for incr. comp.?
|
let owner = self.tcx.hir_owner(def_id);
|
||||||
self.tcx.untracked_resolutions.definitions.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,
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
|
pub fn iter_local_def_id(&self) -> impl Iterator<Item = LocalDefId> + '_ {
|
||||||
|
@ -321,7 +326,7 @@ impl<'hir> Map<'hir> {
|
||||||
if id.local_id == ItemLocalId::from_u32(0) {
|
if id.local_id == ItemLocalId::from_u32(0) {
|
||||||
Some(self.tcx.hir_owner_parent(id.owner))
|
Some(self.tcx.hir_owner_parent(id.owner))
|
||||||
} else {
|
} 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 node = owner.nodes[id.local_id].as_ref()?;
|
||||||
let hir_id = HirId { owner: id.owner, local_id: node.parent };
|
let hir_id = HirId { owner: id.owner, local_id: node.parent };
|
||||||
Some(hir_id)
|
Some(hir_id)
|
||||||
|
@ -335,10 +340,10 @@ impl<'hir> Map<'hir> {
|
||||||
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
|
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
|
||||||
pub fn find(&self, id: HirId) -> Option<Node<'hir>> {
|
pub fn find(&self, id: HirId) -> Option<Node<'hir>> {
|
||||||
if id.local_id == ItemLocalId::from_u32(0) {
|
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())
|
Some(owner.node.into())
|
||||||
} else {
|
} 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 node = owner.nodes[id.local_id].as_ref()?;
|
||||||
Some(node.node)
|
Some(node.node)
|
||||||
}
|
}
|
||||||
|
@ -366,7 +371,7 @@ impl<'hir> Map<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_generics(&self, id: LocalDefId) -> Option<&'hir Generics<'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 {
|
match node.node {
|
||||||
OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics),
|
OwnerNode::ImplItem(impl_item) => Some(&impl_item.generics),
|
||||||
OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics),
|
OwnerNode::TraitItem(trait_item) => Some(&trait_item.generics),
|
||||||
|
@ -522,7 +527,7 @@ impl<'hir> Map<'hir> {
|
||||||
.owners
|
.owners
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.flat_map(move |(owner, owner_info)| {
|
.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, _)| {
|
Some(bodies.iter().map(move |&(local_id, _)| {
|
||||||
let hir_id = HirId { owner, local_id };
|
let hir_id = HirId { owner, local_id };
|
||||||
let body_id = BodyId { hir_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)| {
|
par_iter(&self.krate().owners.raw).enumerate().for_each(|(owner, owner_info)| {
|
||||||
let owner = LocalDefId::new(owner);
|
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, _)| {
|
par_iter(owner_info.nodes.bodies.range(..)).for_each(|(local_id, _)| {
|
||||||
let hir_id = HirId { owner, local_id: *local_id };
|
let hir_id = HirId { owner, local_id: *local_id };
|
||||||
let body_id = BodyId { hir_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) {
|
pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
|
||||||
let hir_id = HirId::make_owner(module);
|
let hir_id = HirId::make_owner(module);
|
||||||
match self.tcx.hir_owner(module).map(|o| o.node) {
|
match self.tcx.hir_owner(module).map(|o| o.node) {
|
||||||
Some(OwnerNode::Item(&Item { span, kind: ItemKind::Mod(ref m), .. })) => {
|
MaybeOwner::Owner(OwnerNode::Item(&Item {
|
||||||
(m, span, hir_id)
|
span, kind: ItemKind::Mod(ref m), ..
|
||||||
}
|
})) => (m, span, hir_id),
|
||||||
Some(OwnerNode::Crate(item)) => (item, item.inner, hir_id),
|
MaybeOwner::Owner(OwnerNode::Crate(item)) => (item, item.inner, hir_id),
|
||||||
node => panic!("not a module: {:?}", node),
|
node => panic!("not a module: {:?}", node),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -601,7 +606,7 @@ impl<'hir> Map<'hir> {
|
||||||
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
|
pub fn walk_attributes(self, visitor: &mut impl Visitor<'hir>) {
|
||||||
let krate = self.krate();
|
let krate = self.krate();
|
||||||
for (owner, info) in krate.owners.iter_enumerated() {
|
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() {
|
for (local_id, attrs) in info.attrs.map.iter() {
|
||||||
let id = HirId { owner, local_id: *local_id };
|
let id = HirId { owner, local_id: *local_id };
|
||||||
for a in *attrs {
|
for a in *attrs {
|
||||||
|
@ -625,7 +630,7 @@ impl<'hir> Map<'hir> {
|
||||||
V: itemlikevisit::ItemLikeVisitor<'hir>,
|
V: itemlikevisit::ItemLikeVisitor<'hir>,
|
||||||
{
|
{
|
||||||
let krate = self.krate();
|
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() {
|
match owner.node() {
|
||||||
OwnerNode::Item(item) => visitor.visit_item(item),
|
OwnerNode::Item(item) => visitor.visit_item(item),
|
||||||
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
|
OwnerNode::ForeignItem(item) => visitor.visit_foreign_item(item),
|
||||||
|
@ -642,12 +647,14 @@ impl<'hir> Map<'hir> {
|
||||||
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
|
V: itemlikevisit::ParItemLikeVisitor<'hir> + Sync + Send,
|
||||||
{
|
{
|
||||||
let krate = self.krate();
|
let krate = self.krate();
|
||||||
par_for_each_in(&krate.owners.raw, |owner| match owner.as_ref().map(OwnerInfo::node) {
|
par_for_each_in(&krate.owners.raw, |owner| match owner.map(OwnerInfo::node) {
|
||||||
Some(OwnerNode::Item(item)) => visitor.visit_item(item),
|
MaybeOwner::Owner(OwnerNode::Item(item)) => visitor.visit_item(item),
|
||||||
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
|
MaybeOwner::Owner(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
|
||||||
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
|
MaybeOwner::Owner(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
|
||||||
Some(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
|
MaybeOwner::Owner(OwnerNode::TraitItem(item)) => visitor.visit_trait_item(item),
|
||||||
Some(OwnerNode::Crate(_)) | None => {}
|
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 {
|
pub fn get_foreign_abi(&self, hir_id: HirId) -> Abi {
|
||||||
let parent = self.get_parent_item(hir_id);
|
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
|
if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node.node
|
||||||
{
|
{
|
||||||
return *abi;
|
return *abi;
|
||||||
|
@ -892,21 +899,21 @@ impl<'hir> Map<'hir> {
|
||||||
|
|
||||||
pub fn expect_item(&self, id: LocalDefId) -> &'hir Item<'hir> {
|
pub fn expect_item(&self, id: LocalDefId) -> &'hir Item<'hir> {
|
||||||
match self.tcx.hir_owner(id) {
|
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))),
|
_ => bug!("expected item, found {}", self.node_to_string(HirId::make_owner(id))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_impl_item(&self, id: LocalDefId) -> &'hir ImplItem<'hir> {
|
pub fn expect_impl_item(&self, id: LocalDefId) -> &'hir ImplItem<'hir> {
|
||||||
match self.tcx.hir_owner(id) {
|
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))),
|
_ => bug!("expected impl item, found {}", self.node_to_string(HirId::make_owner(id))),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn expect_trait_item(&self, id: LocalDefId) -> &'hir TraitItem<'hir> {
|
pub fn expect_trait_item(&self, id: LocalDefId) -> &'hir TraitItem<'hir> {
|
||||||
match self.tcx.hir_owner(id) {
|
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))),
|
_ => 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> {
|
pub fn expect_foreign_item(&self, id: LocalDefId) -> &'hir ForeignItem<'hir> {
|
||||||
match self.tcx.hir_owner(id) {
|
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)))
|
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
|
.owners
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.filter_map(|(def_id, info)| {
|
.filter_map(|(def_id, info)| {
|
||||||
let _ = info.as_ref()?;
|
let _ = info.as_owner()?;
|
||||||
let def_path_hash = definitions.def_path_hash(def_id);
|
let def_path_hash = definitions.def_path_hash(def_id);
|
||||||
let span = definitions.def_span(def_id);
|
let span = definitions.def_span(def_id);
|
||||||
debug_assert_eq!(span.parent(), None);
|
debug_assert_eq!(span.parent(), None);
|
||||||
|
|
|
@ -65,20 +65,20 @@ pub fn provide(providers: &mut Providers) {
|
||||||
providers.crate_hash = map::crate_hash;
|
providers.crate_hash = map::crate_hash;
|
||||||
providers.hir_module_items = map::hir_module_items;
|
providers.hir_module_items = map::hir_module_items;
|
||||||
providers.hir_owner = |tcx, id| {
|
providers.hir_owner = |tcx, id| {
|
||||||
let owner = tcx.hir_crate(()).owners.get(id)?.as_ref()?;
|
tcx.hir_crate(()).owners[id].map(|owner| {
|
||||||
let node = owner.node();
|
let node = owner.nodes.node();
|
||||||
Some(Owner { node, hash_without_bodies: owner.nodes.hash_without_bodies })
|
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| {
|
providers.hir_owner_parent = |tcx, id| {
|
||||||
// Accessing the def_key is ok since its value is hashed as part of `id`'s DefPathHash.
|
// 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 = tcx.untracked_resolutions.definitions.def_key(id).parent;
|
||||||
let parent = parent.map_or(CRATE_HIR_ID, |local_def_index| {
|
let parent = parent.map_or(CRATE_HIR_ID, |local_def_index| {
|
||||||
let def_id = LocalDefId { local_def_index };
|
let def_id = LocalDefId { local_def_index };
|
||||||
let mut parent_hir_id =
|
let mut parent_hir_id = tcx.hir().local_def_id_to_hir_id(def_id);
|
||||||
tcx.untracked_resolutions.definitions.local_def_id_to_hir_id(def_id);
|
|
||||||
if let Some(local_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;
|
parent_hir_id.local_id = *local_id;
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ pub fn provide(providers: &mut Providers) {
|
||||||
parent
|
parent
|
||||||
};
|
};
|
||||||
providers.hir_attrs =
|
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.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.def_span = |tcx, def_id| tcx.hir().span_if_local(def_id).unwrap_or(DUMMY_SP);
|
||||||
providers.fn_arg_names = |tcx, id| {
|
providers.fn_arg_names = |tcx, id| {
|
||||||
|
@ -111,4 +111,6 @@ pub fn provide(providers: &mut Providers) {
|
||||||
let id = id.expect_local();
|
let id = id.expect_local();
|
||||||
tcx.resolutions(()).definitions.expansion_that_defined(id)
|
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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -52,7 +52,7 @@ rustc_queries! {
|
||||||
///
|
///
|
||||||
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||||
/// Avoid calling this query directly.
|
/// Avoid calling this query directly.
|
||||||
query hir_owner(key: LocalDefId) -> Option<crate::hir::Owner<'tcx>> {
|
query hir_owner(key: LocalDefId) -> hir::MaybeOwner<crate::hir::Owner<'tcx>> {
|
||||||
desc { |tcx| "HIR owner of `{}`", tcx.def_path_str(key.to_def_id()) }
|
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()`.
|
/// This can be conveniently accessed by methods on `tcx.hir()`.
|
||||||
/// Avoid calling this query directly.
|
/// 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()) }
|
desc { |tcx| "HIR owner items in `{}`", tcx.def_path_str(key.to_def_id()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -2875,8 +2875,6 @@ fn ptr_eq<T, U>(t: *const T, u: *const U) -> bool {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn provide(providers: &mut ty::query::Providers) {
|
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.resolutions = |tcx, ()| &tcx.untracked_resolutions;
|
||||||
providers.module_reexports =
|
providers.module_reexports =
|
||||||
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
|
|tcx, id| tcx.resolutions(()).reexport_map.get(&id).map(|v| &v[..]);
|
||||||
|
|
|
@ -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 hcx = tcx.create_no_span_stable_hashing_context();
|
||||||
let mut stable_hasher = StableHasher::new();
|
let mut stable_hasher = StableHasher::new();
|
||||||
let owner = hir_body.id().hir_id.owner;
|
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| {
|
hcx.with_hir_bodies(false, owner, bodies, |hcx| {
|
||||||
hir_body.value.hash_stable(hcx, &mut stable_hasher)
|
hir_body.value.hash_stable(hcx, &mut stable_hasher)
|
||||||
});
|
});
|
||||||
|
|
|
@ -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);
|
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
|
// Ensure that the parent of the def is an item, not HRTB
|
||||||
let parent_id = self.tcx.hir().get_parent_node(hir_id);
|
let parent_id = self.tcx.hir().get_parent_node(hir_id);
|
||||||
// FIXME(cjgillot) Can this check be replaced by
|
if !parent_id.is_owner() {
|
||||||
// `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 !self.trait_definition_only {
|
if !self.trait_definition_only {
|
||||||
struct_span_err!(
|
struct_span_err!(
|
||||||
self.tcx.sess,
|
self.tcx.sess,
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue