Auto merge of #83723 - cjgillot:ownernode, r=petrochenkov
Store all HIR owners in the same container This replaces the previous storage in a BTreeMap for each of Item/ImplItem/TraitItem/ForeignItem. This should allow for a more compact storage. Based on https://github.com/rust-lang/rust/pull/83114
This commit is contained in:
@@ -7,7 +7,7 @@ use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||
use rustc_hir as hir;
|
||||
use rustc_hir::def_id::LocalDefId;
|
||||
use rustc_hir::def_id::CRATE_DEF_INDEX;
|
||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
||||
use rustc_hir::definitions;
|
||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||
use rustc_hir::*;
|
||||
@@ -75,46 +75,20 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
arena: &'hir Arena<'hir>,
|
||||
krate: &'hir Crate<'hir>,
|
||||
definitions: &'a definitions::Definitions,
|
||||
mut hcx: StableHashingContext<'a>,
|
||||
hcx: StableHashingContext<'a>,
|
||||
) -> NodeCollector<'a, 'hir> {
|
||||
let hash = {
|
||||
let Crate {
|
||||
ref item,
|
||||
// These fields are handled separately:
|
||||
exported_macros: _,
|
||||
non_exported_macro_attrs: _,
|
||||
items: _,
|
||||
trait_items: _,
|
||||
impl_items: _,
|
||||
foreign_items: _,
|
||||
bodies: _,
|
||||
trait_impls: _,
|
||||
body_ids: _,
|
||||
modules: _,
|
||||
proc_macros: _,
|
||||
trait_map: _,
|
||||
attrs: _,
|
||||
} = *krate;
|
||||
|
||||
hash_body(&mut hcx, item)
|
||||
};
|
||||
|
||||
let mut collector = NodeCollector {
|
||||
arena,
|
||||
krate,
|
||||
source_map: sess.source_map(),
|
||||
parent_node: hir::CRATE_HIR_ID,
|
||||
current_dep_node_owner: LocalDefId { local_def_index: CRATE_DEF_INDEX },
|
||||
current_dep_node_owner: CRATE_DEF_ID,
|
||||
definitions,
|
||||
hcx,
|
||||
map: IndexVec::from_fn_n(|_| None, definitions.def_index_count()),
|
||||
parenting: FxHashMap::default(),
|
||||
};
|
||||
collector.insert_entry(
|
||||
hir::CRATE_HIR_ID,
|
||||
Entry { parent: hir::CRATE_HIR_ID, node: Node::Crate(&krate.item) },
|
||||
hash,
|
||||
);
|
||||
collector.insert_owner(CRATE_DEF_ID, OwnerNode::Crate(krate.module()));
|
||||
|
||||
collector
|
||||
}
|
||||
@@ -128,53 +102,20 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
IndexedHir { map: self.map, parenting: self.parenting }
|
||||
}
|
||||
|
||||
fn insert_entry(&mut self, id: HirId, entry: Entry<'hir>, hash: Fingerprint) {
|
||||
let i = id.local_id.as_u32() as usize;
|
||||
fn insert_owner(&mut self, owner: LocalDefId, node: OwnerNode<'hir>) {
|
||||
let hash = hash_body(&mut self.hcx, node);
|
||||
|
||||
let arena = self.arena;
|
||||
let mut nodes = IndexVec::new();
|
||||
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
|
||||
|
||||
let data = &mut self.map[id.owner];
|
||||
|
||||
if i == 0 {
|
||||
debug_assert!(data.is_none());
|
||||
*data = Some(arena.alloc(OwnerNodes {
|
||||
hash,
|
||||
nodes: IndexVec::new(),
|
||||
bodies: FxHashMap::default(),
|
||||
}));
|
||||
|
||||
let dk_parent = self.definitions.def_key(id.owner).parent;
|
||||
if let Some(dk_parent) = dk_parent {
|
||||
let dk_parent = LocalDefId { local_def_index: dk_parent };
|
||||
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
|
||||
if dk_parent.owner != entry.parent.owner {
|
||||
panic!(
|
||||
"Different parents for {:?} => dk_parent={:?} actual={:?}",
|
||||
id.owner, dk_parent, entry.parent,
|
||||
)
|
||||
}
|
||||
|
||||
debug_assert_eq!(self.parenting.get(&id.owner), Some(&entry.parent));
|
||||
}
|
||||
} else {
|
||||
debug_assert_eq!(entry.parent.owner, id.owner);
|
||||
}
|
||||
|
||||
let data = data.as_mut().unwrap();
|
||||
|
||||
insert_vec_map(
|
||||
&mut data.nodes,
|
||||
id.local_id,
|
||||
ParentedNode { parent: entry.parent.local_id, node: entry.node },
|
||||
);
|
||||
debug_assert!(self.map[owner].is_none());
|
||||
self.map[owner] =
|
||||
Some(self.arena.alloc(OwnerNodes { hash, nodes, bodies: FxHashMap::default() }));
|
||||
}
|
||||
|
||||
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
|
||||
self.insert_with_hash(span, hir_id, node, Fingerprint::ZERO)
|
||||
}
|
||||
|
||||
fn insert_with_hash(&mut self, span: Span, hir_id: HirId, node: Node<'hir>, hash: Fingerprint) {
|
||||
let entry = Entry { parent: self.parent_node, node };
|
||||
debug_assert_eq!(self.current_dep_node_owner, hir_id.owner);
|
||||
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
|
||||
|
||||
// Make sure that the DepNode of some node coincides with the HirId
|
||||
// owner of that node.
|
||||
@@ -201,7 +142,14 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
}
|
||||
}
|
||||
|
||||
self.insert_entry(hir_id, entry, hash);
|
||||
let nodes = self.map[hir_id.owner].as_mut().unwrap();
|
||||
|
||||
debug_assert_eq!(self.parent_node.owner, self.current_dep_node_owner);
|
||||
insert_vec_map(
|
||||
&mut nodes.nodes,
|
||||
hir_id.local_id,
|
||||
ParentedNode { parent: self.parent_node.local_id, node: node },
|
||||
);
|
||||
}
|
||||
|
||||
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
|
||||
@@ -211,21 +159,15 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||
self.parent_node = parent_node;
|
||||
}
|
||||
|
||||
fn with_dep_node_owner<
|
||||
T: for<'b> HashStable<StableHashingContext<'b>>,
|
||||
F: FnOnce(&mut Self, Fingerprint),
|
||||
>(
|
||||
&mut self,
|
||||
dep_node_owner: LocalDefId,
|
||||
item_like: &T,
|
||||
f: F,
|
||||
) {
|
||||
fn with_dep_node_owner(&mut self, dep_node_owner: LocalDefId, f: impl FnOnce(&mut Self)) {
|
||||
let prev_owner = self.current_dep_node_owner;
|
||||
let hash = hash_body(&mut self.hcx, item_like);
|
||||
let prev_parent = self.parent_node;
|
||||
|
||||
self.current_dep_node_owner = dep_node_owner;
|
||||
f(self, hash);
|
||||
self.parent_node = HirId::make_owner(dep_node_owner);
|
||||
f(self);
|
||||
self.current_dep_node_owner = prev_owner;
|
||||
self.parent_node = prev_parent;
|
||||
}
|
||||
|
||||
fn insert_nested(&mut self, item: LocalDefId) {
|
||||
@@ -291,28 +233,22 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||
|
||||
fn visit_item(&mut self, i: &'hir Item<'hir>) {
|
||||
debug!("visit_item: {:?}", i);
|
||||
self.with_dep_node_owner(i.def_id, i, |this, hash| {
|
||||
let hir_id = i.hir_id();
|
||||
this.insert_with_hash(i.span, hir_id, Node::Item(i), hash);
|
||||
this.with_parent(hir_id, |this| {
|
||||
if let ItemKind::Struct(ref struct_def, _) = i.kind {
|
||||
// If this is a tuple or unit-like struct, register the constructor.
|
||||
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
|
||||
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
|
||||
}
|
||||
self.insert_owner(i.def_id, OwnerNode::Item(i));
|
||||
self.with_dep_node_owner(i.def_id, |this| {
|
||||
if let ItemKind::Struct(ref struct_def, _) = i.kind {
|
||||
// If this is a tuple or unit-like struct, register the constructor.
|
||||
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
|
||||
this.insert(i.span, ctor_hir_id, Node::Ctor(struct_def));
|
||||
}
|
||||
intravisit::walk_item(this, i);
|
||||
});
|
||||
}
|
||||
intravisit::walk_item(this, i);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
|
||||
self.with_dep_node_owner(fi.def_id, fi, |this, hash| {
|
||||
this.insert_with_hash(fi.span, fi.hir_id(), Node::ForeignItem(fi), hash);
|
||||
|
||||
this.with_parent(fi.hir_id(), |this| {
|
||||
intravisit::walk_foreign_item(this, fi);
|
||||
});
|
||||
self.insert_owner(fi.def_id, OwnerNode::ForeignItem(fi));
|
||||
self.with_dep_node_owner(fi.def_id, |this| {
|
||||
intravisit::walk_foreign_item(this, fi);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -322,26 +258,22 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||
}
|
||||
|
||||
fn visit_const_param_default(&mut self, param: HirId, ct: &'hir AnonConst) {
|
||||
self.with_parent(param, |this| intravisit::walk_const_param_default(this, ct))
|
||||
self.with_parent(param, |this| {
|
||||
intravisit::walk_const_param_default(this, ct);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
|
||||
self.with_dep_node_owner(ti.def_id, ti, |this, hash| {
|
||||
this.insert_with_hash(ti.span, ti.hir_id(), Node::TraitItem(ti), hash);
|
||||
|
||||
this.with_parent(ti.hir_id(), |this| {
|
||||
intravisit::walk_trait_item(this, ti);
|
||||
});
|
||||
self.insert_owner(ti.def_id, OwnerNode::TraitItem(ti));
|
||||
self.with_dep_node_owner(ti.def_id, |this| {
|
||||
intravisit::walk_trait_item(this, ti);
|
||||
});
|
||||
}
|
||||
|
||||
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
|
||||
self.with_dep_node_owner(ii.def_id, ii, |this, hash| {
|
||||
this.insert_with_hash(ii.span, ii.hir_id(), Node::ImplItem(ii), hash);
|
||||
|
||||
this.with_parent(ii.hir_id(), |this| {
|
||||
intravisit::walk_impl_item(this, ii);
|
||||
});
|
||||
self.insert_owner(ii.def_id, OwnerNode::ImplItem(ii));
|
||||
self.with_dep_node_owner(ii.def_id, |this| {
|
||||
intravisit::walk_impl_item(this, ii);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -433,7 +365,9 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||
|
||||
fn visit_local(&mut self, l: &'hir Local<'hir>) {
|
||||
self.insert(l.span, l.hir_id, Node::Local(l));
|
||||
self.with_parent(l.hir_id, |this| intravisit::walk_local(this, l))
|
||||
self.with_parent(l.hir_id, |this| {
|
||||
intravisit::walk_local(this, l);
|
||||
})
|
||||
}
|
||||
|
||||
fn visit_lifetime(&mut self, lifetime: &'hir Lifetime) {
|
||||
@@ -460,16 +394,9 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||
let parent = def_key.parent.map_or(hir::CRATE_HIR_ID, |local_def_index| {
|
||||
self.definitions.local_def_id_to_hir_id(LocalDefId { local_def_index })
|
||||
});
|
||||
self.insert_owner(macro_def.def_id, OwnerNode::MacroDef(macro_def));
|
||||
self.with_parent(parent, |this| {
|
||||
this.insert_nested(macro_def.def_id);
|
||||
this.with_dep_node_owner(macro_def.def_id, macro_def, |this, hash| {
|
||||
this.insert_with_hash(
|
||||
macro_def.span,
|
||||
macro_def.hir_id(),
|
||||
Node::MacroDef(macro_def),
|
||||
hash,
|
||||
);
|
||||
})
|
||||
});
|
||||
}
|
||||
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
use self::collector::NodeCollector;
|
||||
|
||||
use crate::hir::{AttributeMap, IndexedHir};
|
||||
use crate::hir::{AttributeMap, IndexedHir, Owner};
|
||||
use crate::ty::TyCtxt;
|
||||
use rustc_ast as ast;
|
||||
use rustc_data_structures::fingerprint::Fingerprint;
|
||||
@@ -121,13 +121,13 @@ pub struct ParentOwnerIterator<'map, 'hir> {
|
||||
}
|
||||
|
||||
impl<'hir> Iterator for ParentOwnerIterator<'_, 'hir> {
|
||||
type Item = (HirId, Node<'hir>);
|
||||
type Item = (HirId, OwnerNode<'hir>);
|
||||
|
||||
fn next(&mut self) -> Option<Self::Item> {
|
||||
if self.current_id.local_id.index() != 0 {
|
||||
self.current_id.local_id = ItemLocalId::new(0);
|
||||
if let Some(node) = self.map.find(self.current_id) {
|
||||
return Some((self.current_id, node));
|
||||
if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) {
|
||||
return Some((self.current_id, node.node));
|
||||
}
|
||||
}
|
||||
if self.current_id == CRATE_HIR_ID {
|
||||
@@ -144,8 +144,8 @@ 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.find(self.current_id) {
|
||||
return Some((self.current_id, node));
|
||||
if let Some(node) = self.map.tcx.hir_owner(self.current_id.owner) {
|
||||
return Some((self.current_id, node.node));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -313,7 +313,7 @@ impl<'hir> Map<'hir> {
|
||||
pub fn find(&self, id: HirId) -> Option<Node<'hir>> {
|
||||
if id.local_id == ItemLocalId::from_u32(0) {
|
||||
let owner = self.tcx.hir_owner(id.owner)?;
|
||||
Some(owner.node)
|
||||
Some(owner.node.into())
|
||||
} else {
|
||||
let owner = self.tcx.hir_owner_nodes(id.owner)?;
|
||||
let node = owner.nodes[id.local_id].as_ref()?;
|
||||
@@ -331,10 +331,12 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
|
||||
pub fn get_generics(&self, id: DefId) -> Option<&'hir Generics<'hir>> {
|
||||
self.get_if_local(id).and_then(|node| match &node {
|
||||
Node::ImplItem(impl_item) => Some(&impl_item.generics),
|
||||
Node::TraitItem(trait_item) => Some(&trait_item.generics),
|
||||
Node::Item(Item {
|
||||
let id = id.as_local()?;
|
||||
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),
|
||||
OwnerNode::Item(Item {
|
||||
kind:
|
||||
ItemKind::Fn(_, generics, _)
|
||||
| ItemKind::TyAlias(_, generics)
|
||||
@@ -347,35 +349,23 @@ impl<'hir> Map<'hir> {
|
||||
..
|
||||
}) => Some(generics),
|
||||
_ => None,
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
|
||||
match self.find(id.hir_id()).unwrap() {
|
||||
Node::Item(item) => item,
|
||||
_ => bug!(),
|
||||
}
|
||||
self.tcx.hir_owner(id.def_id).unwrap().node.expect_item()
|
||||
}
|
||||
|
||||
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
|
||||
match self.find(id.hir_id()).unwrap() {
|
||||
Node::TraitItem(item) => item,
|
||||
_ => bug!(),
|
||||
}
|
||||
self.tcx.hir_owner(id.def_id).unwrap().node.expect_trait_item()
|
||||
}
|
||||
|
||||
pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
|
||||
match self.find(id.hir_id()).unwrap() {
|
||||
Node::ImplItem(item) => item,
|
||||
_ => bug!(),
|
||||
}
|
||||
self.tcx.hir_owner(id.def_id).unwrap().node.expect_impl_item()
|
||||
}
|
||||
|
||||
pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
|
||||
match self.find(id.hir_id()).unwrap() {
|
||||
Node::ForeignItem(item) => item,
|
||||
_ => bug!(),
|
||||
}
|
||||
self.tcx.hir_owner(id.def_id).unwrap().node.expect_foreign_item()
|
||||
}
|
||||
|
||||
pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
|
||||
@@ -519,10 +509,12 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
|
||||
pub fn get_module(&self, module: LocalDefId) -> (&'hir Mod<'hir>, Span, HirId) {
|
||||
let hir_id = self.local_def_id_to_hir_id(module);
|
||||
match self.get(hir_id) {
|
||||
Node::Item(&Item { span, kind: ItemKind::Mod(ref m), .. }) => (m, span, hir_id),
|
||||
Node::Crate(item) => (&item, item.inner, hir_id),
|
||||
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),
|
||||
node => panic!("not a module: {:?}", node),
|
||||
}
|
||||
}
|
||||
@@ -554,8 +546,8 @@ impl<'hir> Map<'hir> {
|
||||
where
|
||||
V: Visitor<'hir>,
|
||||
{
|
||||
for id in self.krate().exported_macros {
|
||||
visitor.visit_macro_def(self.expect_macro_def(id.hir_id()));
|
||||
for macro_def in self.krate().exported_macros() {
|
||||
visitor.visit_macro_def(macro_def);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -659,24 +651,20 @@ impl<'hir> Map<'hir> {
|
||||
/// in the HIR which is recorded by the map and is an item, either an item
|
||||
/// in a module, trait, or impl.
|
||||
pub fn get_parent_item(&self, hir_id: HirId) -> HirId {
|
||||
for (hir_id, node) in self.parent_owner_iter(hir_id) {
|
||||
if let Node::Crate(_)
|
||||
| Node::Item(_)
|
||||
| Node::ForeignItem(_)
|
||||
| Node::TraitItem(_)
|
||||
| Node::ImplItem(_) = node
|
||||
{
|
||||
return hir_id;
|
||||
}
|
||||
if let Some((hir_id, _node)) = self.parent_owner_iter(hir_id).next() {
|
||||
// A MacroDef does not have children.
|
||||
debug_assert!(!matches!(_node, OwnerNode::MacroDef(_)));
|
||||
hir_id
|
||||
} else {
|
||||
CRATE_HIR_ID
|
||||
}
|
||||
CRATE_HIR_ID
|
||||
}
|
||||
|
||||
/// Returns the `HirId` of `id`'s nearest module parent, or `id` itself if no
|
||||
/// module parent is in this map.
|
||||
pub(super) fn get_module_parent_node(&self, hir_id: HirId) -> HirId {
|
||||
for (hir_id, node) in self.parent_owner_iter(hir_id) {
|
||||
if let Node::Item(&Item { kind: ItemKind::Mod(_), .. }) = node {
|
||||
if let OwnerNode::Item(&Item { kind: ItemKind::Mod(_), .. }) = node {
|
||||
return hir_id;
|
||||
}
|
||||
}
|
||||
@@ -749,8 +737,9 @@ 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.find(parent) {
|
||||
if let Node::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node {
|
||||
if let Some(node) = self.tcx.hir_owner(self.local_def_id(parent)) {
|
||||
if let OwnerNode::Item(Item { kind: ItemKind::ForeignMod { abi, .. }, .. }) = node.node
|
||||
{
|
||||
return *abi;
|
||||
}
|
||||
}
|
||||
@@ -758,22 +747,22 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
|
||||
pub fn expect_item(&self, id: HirId) -> &'hir Item<'hir> {
|
||||
match self.find(id) {
|
||||
Some(Node::Item(item)) => item,
|
||||
match self.tcx.hir_owner(id.expect_owner()) {
|
||||
Some(Owner { node: OwnerNode::Item(item) }) => item,
|
||||
_ => bug!("expected item, found {}", self.node_to_string(id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_impl_item(&self, id: HirId) -> &'hir ImplItem<'hir> {
|
||||
match self.find(id) {
|
||||
Some(Node::ImplItem(item)) => item,
|
||||
match self.tcx.hir_owner(id.expect_owner()) {
|
||||
Some(Owner { node: OwnerNode::ImplItem(item) }) => item,
|
||||
_ => bug!("expected impl item, found {}", self.node_to_string(id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_trait_item(&self, id: HirId) -> &'hir TraitItem<'hir> {
|
||||
match self.find(id) {
|
||||
Some(Node::TraitItem(item)) => item,
|
||||
match self.tcx.hir_owner(id.expect_owner()) {
|
||||
Some(Owner { node: OwnerNode::TraitItem(item) }) => item,
|
||||
_ => bug!("expected trait item, found {}", self.node_to_string(id)),
|
||||
}
|
||||
}
|
||||
@@ -786,15 +775,15 @@ impl<'hir> Map<'hir> {
|
||||
}
|
||||
|
||||
pub fn expect_foreign_item(&self, id: HirId) -> &'hir ForeignItem<'hir> {
|
||||
match self.find(id) {
|
||||
Some(Node::ForeignItem(item)) => item,
|
||||
match self.tcx.hir_owner(id.expect_owner()) {
|
||||
Some(Owner { node: OwnerNode::ForeignItem(item) }) => item,
|
||||
_ => bug!("expected foreign item, found {}", self.node_to_string(id)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn expect_macro_def(&self, id: HirId) -> &'hir MacroDef<'hir> {
|
||||
match self.find(id) {
|
||||
Some(Node::MacroDef(macro_def)) => macro_def,
|
||||
match self.tcx.hir_owner(id.expect_owner()) {
|
||||
Some(Owner { node: OwnerNode::MacroDef(macro_def) }) => macro_def,
|
||||
_ => bug!("expected macro def, found {}", self.node_to_string(id)),
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user