Perform indexing during lowering.
Do not access DefId<->HirId maps before they are initialized.
This commit is contained in:
parent
c09eaea484
commit
1c7f85f17c
@ -1,5 +1,3 @@
|
|||||||
use crate::hir::map::Map;
|
|
||||||
use crate::hir::{IndexedHir, OwnerNodes, ParentedNode};
|
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
use rustc_data_structures::fx::FxHashMap;
|
||||||
use rustc_hir as hir;
|
use rustc_hir as hir;
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
@ -12,16 +10,16 @@ use rustc_span::source_map::SourceMap;
|
|||||||
use rustc_span::{Span, DUMMY_SP};
|
use rustc_span::{Span, DUMMY_SP};
|
||||||
|
|
||||||
use std::iter::repeat;
|
use std::iter::repeat;
|
||||||
|
use tracing::debug;
|
||||||
|
|
||||||
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
|
/// A visitor that walks over the HIR and collects `Node`s into a HIR map.
|
||||||
pub(super) struct NodeCollector<'a, 'hir> {
|
pub(super) struct NodeCollector<'a, 'hir> {
|
||||||
/// The crate
|
|
||||||
krate: &'hir Crate<'hir>,
|
|
||||||
|
|
||||||
/// Source map
|
/// Source map
|
||||||
source_map: &'a SourceMap,
|
source_map: &'a SourceMap,
|
||||||
|
bodies: &'a IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
|
||||||
|
|
||||||
nodes: OwnerNodes<'hir>,
|
/// Outputs
|
||||||
|
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>,
|
||||||
parenting: FxHashMap<LocalDefId, ItemLocalId>,
|
parenting: FxHashMap<LocalDefId, ItemLocalId>,
|
||||||
|
|
||||||
/// The parent of this node
|
/// The parent of this node
|
||||||
@ -42,28 +40,21 @@ fn insert_vec_map<K: Idx, V: Clone>(map: &mut IndexVec<K, Option<V>>, k: K, v: V
|
|||||||
map[k] = Some(v);
|
map[k] = Some(v);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn collect<'a, 'hir: 'a>(
|
pub(super) fn index_hir<'hir>(
|
||||||
sess: &'a Session,
|
sess: &Session,
|
||||||
krate: &'hir Crate<'hir>,
|
definitions: &definitions::Definitions,
|
||||||
definitions: &'a definitions::Definitions,
|
item: hir::OwnerNode<'hir>,
|
||||||
owner: LocalDefId,
|
bodies: &IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
|
||||||
) -> Option<IndexedHir<'hir>> {
|
) -> (IndexVec<ItemLocalId, Option<ParentedNode<'hir>>>, FxHashMap<LocalDefId, ItemLocalId>) {
|
||||||
let info = krate.owners.get(owner)?.as_ref()?;
|
|
||||||
let item = info.node;
|
|
||||||
let mut nodes = IndexVec::new();
|
let mut nodes = IndexVec::new();
|
||||||
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: item.into() }));
|
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: item.into() }));
|
||||||
let mut collector = NodeCollector {
|
let mut collector = NodeCollector {
|
||||||
krate,
|
|
||||||
source_map: sess.source_map(),
|
source_map: sess.source_map(),
|
||||||
owner,
|
|
||||||
parent_node: ItemLocalId::new(0),
|
|
||||||
definitions,
|
definitions,
|
||||||
nodes: OwnerNodes {
|
owner: item.def_id(),
|
||||||
hash: info.hash,
|
parent_node: ItemLocalId::new(0),
|
||||||
node_hash: info.node_hash,
|
|
||||||
nodes,
|
nodes,
|
||||||
bodies: &info.bodies,
|
bodies,
|
||||||
},
|
|
||||||
parenting: FxHashMap::default(),
|
parenting: FxHashMap::default(),
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -75,7 +66,7 @@ pub(super) fn collect<'a, 'hir: 'a>(
|
|||||||
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
|
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
|
||||||
};
|
};
|
||||||
|
|
||||||
Some(IndexedHir { nodes: collector.nodes, parenting: collector.parenting })
|
(collector.nodes, collector.parenting)
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
@ -87,17 +78,11 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
|||||||
// owner of that node.
|
// owner of that node.
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
if hir_id.owner != self.owner {
|
if hir_id.owner != self.owner {
|
||||||
let node_str = match self.definitions.opt_hir_id_to_local_def_id(hir_id) {
|
panic!(
|
||||||
Some(def_id) => self.definitions.def_path(def_id).to_string_no_crate_verbose(),
|
"inconsistent DepNode at `{:?}` for `{:?}`: \
|
||||||
None => format!("{:?}", node),
|
|
||||||
};
|
|
||||||
|
|
||||||
span_bug!(
|
|
||||||
span,
|
|
||||||
"inconsistent DepNode at `{:?}` for `{}`: \
|
|
||||||
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
|
current_dep_node_owner={} ({:?}), hir_id.owner={} ({:?})",
|
||||||
self.source_map.span_to_diagnostic_string(span),
|
self.source_map.span_to_diagnostic_string(span),
|
||||||
node_str,
|
node,
|
||||||
self.definitions.def_path(self.owner).to_string_no_crate_verbose(),
|
self.definitions.def_path(self.owner).to_string_no_crate_verbose(),
|
||||||
self.owner,
|
self.owner,
|
||||||
self.definitions.def_path(hir_id.owner).to_string_no_crate_verbose(),
|
self.definitions.def_path(hir_id.owner).to_string_no_crate_verbose(),
|
||||||
@ -107,7 +92,7 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
insert_vec_map(
|
insert_vec_map(
|
||||||
&mut self.nodes.nodes,
|
&mut self.nodes,
|
||||||
hir_id.local_id,
|
hir_id.local_id,
|
||||||
ParentedNode { parent: self.parent_node, node: node },
|
ParentedNode { parent: self.parent_node, node: node },
|
||||||
);
|
);
|
||||||
@ -122,18 +107,12 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn insert_nested(&mut self, item: LocalDefId) {
|
fn insert_nested(&mut self, item: LocalDefId) {
|
||||||
let dk_parent = self.definitions.def_key(item).parent.unwrap();
|
|
||||||
let dk_parent = LocalDefId { local_def_index: dk_parent };
|
|
||||||
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
|
|
||||||
debug_assert_eq!(dk_parent.owner, self.owner, "Different parents for {:?}", item);
|
|
||||||
if dk_parent.local_id != self.parent_node {
|
|
||||||
self.parenting.insert(item, self.parent_node);
|
self.parenting.insert(item, self.parent_node);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
type Map = Map<'hir>;
|
type Map = !;
|
||||||
|
|
||||||
/// Because we want to track parent items and so forth, enable
|
/// Because we want to track parent items and so forth, enable
|
||||||
/// deep walking so that we walk nested items in the context of
|
/// deep walking so that we walk nested items in the context of
|
||||||
@ -161,8 +140,8 @@ impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn visit_nested_body(&mut self, id: BodyId) {
|
fn visit_nested_body(&mut self, id: BodyId) {
|
||||||
let body = self.krate.body(id);
|
|
||||||
debug_assert_eq!(id.hir_id.owner, self.owner);
|
debug_assert_eq!(id.hir_id.owner, self.owner);
|
||||||
|
let body = self.bodies[id.hir_id.local_id].unwrap();
|
||||||
self.visit_body(body);
|
self.visit_body(body);
|
||||||
}
|
}
|
||||||
|
|
@ -101,7 +101,7 @@ impl<'hir> LoweringContext<'_, 'hir> {
|
|||||||
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].as_ref().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,
|
||||||
_ => &[],
|
_ => &[],
|
||||||
|
@ -33,6 +33,7 @@
|
|||||||
#![feature(crate_visibility_modifier)]
|
#![feature(crate_visibility_modifier)]
|
||||||
#![feature(box_patterns)]
|
#![feature(box_patterns)]
|
||||||
#![feature(iter_zip)]
|
#![feature(iter_zip)]
|
||||||
|
#![feature(never_type)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
use rustc_ast::token::{self, Token};
|
use rustc_ast::token::{self, Token};
|
||||||
@ -78,6 +79,7 @@ macro_rules! arena_vec {
|
|||||||
mod asm;
|
mod asm;
|
||||||
mod block;
|
mod block;
|
||||||
mod expr;
|
mod expr;
|
||||||
|
mod index;
|
||||||
mod item;
|
mod item;
|
||||||
mod pat;
|
mod pat;
|
||||||
mod path;
|
mod path;
|
||||||
@ -434,6 +436,7 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
self.local_node_ids.push(owner);
|
self.local_node_ids.push(owner);
|
||||||
|
|
||||||
let item = f(self);
|
let item = f(self);
|
||||||
|
debug_assert_eq!(def_id, item.def_id());
|
||||||
let info = self.make_owner_info(item);
|
let info = self.make_owner_info(item);
|
||||||
|
|
||||||
self.attrs = current_attrs;
|
self.attrs = current_attrs;
|
||||||
@ -470,8 +473,11 @@ impl<'a, 'hir> LoweringContext<'a, 'hir> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let (hash, node_hash) = self.hash_body(node, &bodies);
|
let (hash, node_hash) = self.hash_body(node, &bodies);
|
||||||
|
let (nodes, parenting) =
|
||||||
|
index::index_hir(self.sess, self.resolver.definitions(), node, &bodies);
|
||||||
|
let nodes = hir::OwnerNodes { hash, node_hash, nodes, bodies };
|
||||||
|
|
||||||
hir::OwnerInfo { hash, node_hash, node, attrs, bodies, trait_map }
|
hir::OwnerInfo { nodes, parenting, attrs, trait_map }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
|
/// Hash the HIR node twice, one deep and one shallow hash. This allows to differentiate
|
||||||
|
@ -37,6 +37,7 @@ macro_rules! arena_types {
|
|||||||
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
|
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
|
||||||
[] local: rustc_hir::Local<$tcx>,
|
[] local: rustc_hir::Local<$tcx>,
|
||||||
[few] mod_: rustc_hir::Mod<$tcx>,
|
[few] mod_: rustc_hir::Mod<$tcx>,
|
||||||
|
[] owner_info: rustc_hir::OwnerInfo<$tcx>,
|
||||||
[] param: rustc_hir::Param<$tcx>,
|
[] param: rustc_hir::Param<$tcx>,
|
||||||
[] pat: rustc_hir::Pat<$tcx>,
|
[] pat: rustc_hir::Pat<$tcx>,
|
||||||
[] path: rustc_hir::Path<$tcx>,
|
[] path: rustc_hir::Path<$tcx>,
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
use crate::def::{CtorKind, DefKind, Res};
|
use crate::def::{CtorKind, DefKind, Res};
|
||||||
use crate::def_id::{DefId, CRATE_DEF_ID};
|
use crate::def_id::DefId;
|
||||||
crate use crate::hir_id::{HirId, ItemLocalId};
|
crate use crate::hir_id::{HirId, ItemLocalId};
|
||||||
use crate::LangItem;
|
use crate::LangItem;
|
||||||
|
|
||||||
@ -663,18 +663,49 @@ pub struct WhereEqPredicate<'hir> {
|
|||||||
pub rhs_ty: &'hir Ty<'hir>,
|
pub rhs_ty: &'hir Ty<'hir>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// HIR node coupled with its parent's id in the same HIR owner.
|
||||||
|
///
|
||||||
|
/// The parent is trash when the node is a HIR owner.
|
||||||
|
#[derive(Clone, Debug)]
|
||||||
|
pub struct ParentedNode<'tcx> {
|
||||||
|
pub parent: ItemLocalId,
|
||||||
|
pub node: Node<'tcx>,
|
||||||
|
}
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct OwnerInfo<'hir> {
|
pub struct OwnerNodes<'tcx> {
|
||||||
pub node: OwnerNode<'hir>,
|
|
||||||
pub attrs: BTreeMap<ItemLocalId, &'hir [Attribute]>,
|
|
||||||
pub bodies: IndexVec<ItemLocalId, Option<&'hir Body<'hir>>>,
|
|
||||||
/// Map indicating what traits are in scope for places where this
|
|
||||||
/// is relevant; generated by resolve.
|
|
||||||
pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
|
|
||||||
/// Pre-computed hash of the full HIR.
|
/// Pre-computed hash of the full HIR.
|
||||||
pub hash: Fingerprint,
|
pub hash: Fingerprint,
|
||||||
/// Pre-computed hash of the top node.
|
/// Pre-computed hash of the top node.
|
||||||
pub node_hash: Fingerprint,
|
pub node_hash: Fingerprint,
|
||||||
|
/// Full HIR for the current owner.
|
||||||
|
// The zeroth node's parent is trash, but is never accessed.
|
||||||
|
pub nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
|
||||||
|
/// Content of local bodies.
|
||||||
|
pub bodies: IndexVec<ItemLocalId, Option<&'tcx Body<'tcx>>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Debug)]
|
||||||
|
pub struct OwnerInfo<'hir> {
|
||||||
|
/// Contents of the HIR.
|
||||||
|
pub nodes: OwnerNodes<'hir>,
|
||||||
|
/// Map from each nested owner to its parent's local id.
|
||||||
|
pub parenting: FxHashMap<LocalDefId, ItemLocalId>,
|
||||||
|
|
||||||
|
pub attrs: BTreeMap<ItemLocalId, &'hir [Attribute]>,
|
||||||
|
/// Map indicating what traits are in scope for places where this
|
||||||
|
/// is relevant; generated by resolve.
|
||||||
|
pub trait_map: FxHashMap<ItemLocalId, Box<[TraitCandidate]>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The top-level data structure that stores the entire contents of
|
/// The top-level data structure that stores the entire contents of
|
||||||
@ -688,39 +719,6 @@ pub struct Crate<'hir> {
|
|||||||
pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
|
pub owners: IndexVec<LocalDefId, Option<OwnerInfo<'hir>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Crate<'hir> {
|
|
||||||
pub fn module(&self) -> &'hir Mod<'hir> {
|
|
||||||
let i = self.owners[CRATE_DEF_ID].as_ref().unwrap().node;
|
|
||||||
if let OwnerNode::Crate(m) = i { m } else { panic!() }
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn item(&self, id: ItemId) -> &'hir Item<'hir> {
|
|
||||||
self.owners[id.def_id].as_ref().unwrap().node.expect_item()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn trait_item(&self, id: TraitItemId) -> &'hir TraitItem<'hir> {
|
|
||||||
self.owners[id.def_id].as_ref().unwrap().node.expect_trait_item()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn impl_item(&self, id: ImplItemId) -> &'hir ImplItem<'hir> {
|
|
||||||
self.owners[id.def_id].as_ref().unwrap().node.expect_impl_item()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir> {
|
|
||||||
self.owners[id.def_id].as_ref().unwrap().node.expect_foreign_item()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn body(&self, id: BodyId) -> &'hir Body<'hir> {
|
|
||||||
let HirId { owner, local_id } = id.hir_id;
|
|
||||||
self.owners[owner].as_ref().unwrap().bodies[local_id].unwrap()
|
|
||||||
}
|
|
||||||
|
|
||||||
pub fn attrs(&self, id: HirId) -> &'hir [Attribute] {
|
|
||||||
let HirId { owner, local_id } = id;
|
|
||||||
&self.owners[owner].as_ref().unwrap().attrs.get(&local_id).map(|la| *la).unwrap_or(&[])
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// A block of statements `{ .. }`, which may have a label (in this case the
|
/// A block of statements `{ .. }`, which may have a label (in this case the
|
||||||
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
|
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
|
||||||
/// the `rules` being anything but `DefaultBlock`.
|
/// the `rules` being anything but `DefaultBlock`.
|
||||||
|
@ -130,6 +130,28 @@ pub trait Map<'hir> {
|
|||||||
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
|
fn foreign_item(&self, id: ForeignItemId) -> &'hir ForeignItem<'hir>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Used when no map is actually available, forcing manual implementation of nested visitors.
|
||||||
|
impl Map<'hir> for ! {
|
||||||
|
fn find(&self, _: HirId) -> Option<Node<'hir>> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn body(&self, _: BodyId) -> &'hir Body<'hir> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn item(&self, _: ItemId) -> &'hir Item<'hir> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn trait_item(&self, _: TraitItemId) -> &'hir TraitItem<'hir> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn impl_item(&self, _: ImplItemId) -> &'hir ImplItem<'hir> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
fn foreign_item(&self, _: ForeignItemId) -> &'hir ForeignItem<'hir> {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/// An erased version of `Map<'hir>`, using dynamic dispatch.
|
/// An erased version of `Map<'hir>`, using dynamic dispatch.
|
||||||
/// NOTE: This type is effectively only usable with `NestedVisitorMap::None`.
|
/// NOTE: This type is effectively only usable with `NestedVisitorMap::None`.
|
||||||
pub struct ErasedMap<'hir>(&'hir dyn Map<'hir>);
|
pub struct ErasedMap<'hir>(&'hir dyn Map<'hir>);
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#![feature(in_band_lifetimes)]
|
#![feature(in_band_lifetimes)]
|
||||||
#![feature(once_cell)]
|
#![feature(once_cell)]
|
||||||
#![feature(min_specialization)]
|
#![feature(min_specialization)]
|
||||||
|
#![feature(never_type)]
|
||||||
#![recursion_limit = "256"]
|
#![recursion_limit = "256"]
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
|
@ -1,8 +1,8 @@
|
|||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||||
|
|
||||||
use crate::hir::{
|
use crate::hir::{
|
||||||
BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem,
|
BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, OwnerNodes,
|
||||||
TraitItemId, Ty, VisibilityKind,
|
TraitItem, TraitItemId, Ty, VisibilityKind,
|
||||||
};
|
};
|
||||||
use crate::hir_id::{HirId, ItemLocalId};
|
use crate::hir_id::{HirId, ItemLocalId};
|
||||||
use rustc_span::def_id::DefPathHash;
|
use rustc_span::def_id::DefPathHash;
|
||||||
@ -209,3 +209,12 @@ impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for Item<'_> {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl<HirCtx: crate::HashStableContext> HashStable<HirCtx> for OwnerNodes<'tcx> {
|
||||||
|
fn hash_stable(&self, hcx: &mut HirCtx, hasher: &mut StableHasher) {
|
||||||
|
// We ignore the `nodes` and `bodies` fields since these refer to information included in
|
||||||
|
// `hash` which is hashed in the collector and used for the crate hash.
|
||||||
|
let OwnerNodes { hash, node_hash: _, nodes: _, bodies: _ } = *self;
|
||||||
|
hash.hash_stable(hcx, hasher);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -92,9 +92,6 @@ macro_rules! arena_types {
|
|||||||
[] tys: rustc_middle::ty::TyS<$tcx>,
|
[] tys: rustc_middle::ty::TyS<$tcx>,
|
||||||
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
|
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
|
||||||
|
|
||||||
// HIR query types
|
|
||||||
[] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
|
|
||||||
|
|
||||||
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
|
// Note that this deliberately duplicates items in the `rustc_hir::arena`,
|
||||||
// since we need to allocate this type on both the `rustc_hir` arena
|
// since we need to allocate this type on both the `rustc_hir` arena
|
||||||
// (during lowering) and the `librustc_middle` arena (for decoding MIR)
|
// (during lowering) and the `librustc_middle` arena (for decoding MIR)
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
use crate::hir::{IndexedHir, ModuleItems, Owner};
|
use crate::hir::{ModuleItems, Owner};
|
||||||
use crate::ty::TyCtxt;
|
use crate::ty::TyCtxt;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
@ -21,7 +21,6 @@ use rustc_target::spec::abi::Abi;
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
|
|
||||||
pub mod blocks;
|
pub mod blocks;
|
||||||
mod collector;
|
|
||||||
|
|
||||||
fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
|
fn fn_decl<'hir>(node: Node<'hir>) -> Option<&'hir FnDecl<'hir>> {
|
||||||
match node {
|
match node {
|
||||||
@ -164,7 +163,7 @@ impl<'hir> Map<'hir> {
|
|||||||
|
|
||||||
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_ref()?.node() {
|
||||||
OwnerNode::Item(item) => Some(item),
|
OwnerNode::Item(item) => Some(item),
|
||||||
_ => None,
|
_ => None,
|
||||||
})
|
})
|
||||||
@ -497,7 +496,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()?.bodies;
|
let bodies = &owner_info.as_ref()?.nodes.bodies;
|
||||||
Some(bodies.iter_enumerated().filter_map(move |(local_id, body)| {
|
Some(bodies.iter_enumerated().filter_map(move |(local_id, body)| {
|
||||||
if body.is_none() {
|
if body.is_none() {
|
||||||
return None;
|
return None;
|
||||||
@ -518,7 +517,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 Some(owner_info) = owner_info {
|
||||||
par_iter(&owner_info.bodies.raw).enumerate().for_each(|(local_id, body)| {
|
par_iter(&owner_info.nodes.bodies.raw).enumerate().for_each(|(local_id, body)| {
|
||||||
if body.is_some() {
|
if body.is_some() {
|
||||||
let local_id = ItemLocalId::new(local_id);
|
let local_id = ItemLocalId::new(local_id);
|
||||||
let hir_id = HirId { owner, local_id };
|
let hir_id = HirId { owner, local_id };
|
||||||
@ -605,7 +604,7 @@ impl<'hir> Map<'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(Option::as_ref) {
|
||||||
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),
|
||||||
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
|
OwnerNode::ImplItem(item) => visitor.visit_impl_item(item),
|
||||||
@ -621,7 +620,7 @@ 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(|o| o.node) {
|
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::Item(item)) => visitor.visit_item(item),
|
||||||
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
|
Some(OwnerNode::ForeignItem(item)) => visitor.visit_foreign_item(item),
|
||||||
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
|
Some(OwnerNode::ImplItem(item)) => visitor.visit_impl_item(item),
|
||||||
@ -1065,20 +1064,6 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn index_hir<'tcx>(
|
|
||||||
tcx: TyCtxt<'tcx>,
|
|
||||||
owner: LocalDefId,
|
|
||||||
) -> Option<&'tcx IndexedHir<'tcx>> {
|
|
||||||
let map = collector::collect(
|
|
||||||
tcx.sess,
|
|
||||||
tcx.untracked_crate,
|
|
||||||
&tcx.untracked_resolutions.definitions,
|
|
||||||
owner,
|
|
||||||
)?;
|
|
||||||
|
|
||||||
Some(&*tcx.arena.alloc(map))
|
|
||||||
}
|
|
||||||
|
|
||||||
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||||
debug_assert_eq!(crate_num, LOCAL_CRATE);
|
debug_assert_eq!(crate_num, LOCAL_CRATE);
|
||||||
let mut hir_body_nodes: Vec<_> = tcx
|
let mut hir_body_nodes: Vec<_> = tcx
|
||||||
@ -1088,7 +1073,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
|||||||
.all_def_path_hashes_and_def_ids()
|
.all_def_path_hashes_and_def_ids()
|
||||||
.filter_map(|(def_path_hash, local_def_index)| {
|
.filter_map(|(def_path_hash, local_def_index)| {
|
||||||
let def_id = LocalDefId { local_def_index };
|
let def_id = LocalDefId { local_def_index };
|
||||||
let hash = tcx.index_hir(def_id).as_ref()?.nodes.hash;
|
let hash = tcx.hir_crate(()).owners[def_id].as_ref()?.nodes.hash;
|
||||||
Some((def_path_hash, hash, def_id))
|
Some((def_path_hash, hash, def_id))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -10,24 +10,13 @@ use crate::ty::query::Providers;
|
|||||||
use crate::ty::TyCtxt;
|
use crate::ty::TyCtxt;
|
||||||
use rustc_ast::Attribute;
|
use rustc_ast::Attribute;
|
||||||
use rustc_data_structures::fingerprint::Fingerprint;
|
use rustc_data_structures::fingerprint::Fingerprint;
|
||||||
use rustc_data_structures::fx::FxHashMap;
|
|
||||||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
use rustc_data_structures::stable_hasher::{HashStable, StableHasher};
|
||||||
use rustc_hir::def_id::LocalDefId;
|
use rustc_hir::def_id::LocalDefId;
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
use rustc_index::vec::{Idx, IndexVec};
|
|
||||||
use rustc_query_system::ich::StableHashingContext;
|
use rustc_query_system::ich::StableHashingContext;
|
||||||
use rustc_span::DUMMY_SP;
|
use rustc_span::DUMMY_SP;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
|
|
||||||
/// Result of HIR indexing for a given HIR owner.
|
|
||||||
#[derive(Debug, HashStable)]
|
|
||||||
pub struct IndexedHir<'hir> {
|
|
||||||
/// Contents of the HIR.
|
|
||||||
nodes: OwnerNodes<'hir>,
|
|
||||||
/// Map from each nested owner to its parent's local id.
|
|
||||||
parenting: FxHashMap<LocalDefId, ItemLocalId>,
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Top-level HIR node for current owner. This only contains the node for which
|
/// Top-level HIR node for current owner. This only contains the node for which
|
||||||
/// `HirId::local_id == 0`, and excludes bodies.
|
/// `HirId::local_id == 0`, and excludes bodies.
|
||||||
///
|
///
|
||||||
@ -47,38 +36,6 @@ impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for Owner<'tcx> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// HIR node coupled with its parent's id in the same HIR owner.
|
|
||||||
///
|
|
||||||
/// The parent is trash when the node is a HIR owner.
|
|
||||||
#[derive(Clone, Debug)]
|
|
||||||
pub struct ParentedNode<'tcx> {
|
|
||||||
parent: ItemLocalId,
|
|
||||||
node: Node<'tcx>,
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub struct OwnerNodes<'tcx> {
|
|
||||||
/// Pre-computed hash of the full HIR.
|
|
||||||
hash: Fingerprint,
|
|
||||||
/// Pre-computed hash of the top node.
|
|
||||||
node_hash: Fingerprint,
|
|
||||||
/// Full HIR for the current owner.
|
|
||||||
// The zeroth node's parent is trash, but is never accessed.
|
|
||||||
nodes: IndexVec<ItemLocalId, Option<ParentedNode<'tcx>>>,
|
|
||||||
/// Content of local bodies.
|
|
||||||
bodies: &'tcx IndexVec<ItemLocalId, Option<&'tcx Body<'tcx>>>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl<'a, 'tcx> HashStable<StableHashingContext<'a>> for OwnerNodes<'tcx> {
|
|
||||||
#[inline]
|
|
||||||
fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) {
|
|
||||||
// We ignore the `nodes` and `bodies` fields since these refer to information included in
|
|
||||||
// `hash` which is hashed in the collector and used for the crate hash.
|
|
||||||
let OwnerNodes { hash, node_hash: _, nodes: _, bodies: _ } = *self;
|
|
||||||
hash.hash_stable(hcx, hasher);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Attributes owner by a HIR owner.
|
/// Attributes owner by a HIR owner.
|
||||||
#[derive(Copy, Clone, Debug, HashStable)]
|
#[derive(Copy, Clone, Debug, HashStable)]
|
||||||
pub struct AttributeMap<'tcx> {
|
pub struct AttributeMap<'tcx> {
|
||||||
@ -125,23 +82,23 @@ pub fn provide(providers: &mut Providers) {
|
|||||||
hir.local_def_id(hir.get_module_parent_node(hir.local_def_id_to_hir_id(id)))
|
hir.local_def_id(hir.get_module_parent_node(hir.local_def_id_to_hir_id(id)))
|
||||||
};
|
};
|
||||||
providers.hir_crate = |tcx, ()| tcx.untracked_crate;
|
providers.hir_crate = |tcx, ()| tcx.untracked_crate;
|
||||||
providers.index_hir = map::index_hir;
|
|
||||||
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.index_hir(id)?;
|
let owner = tcx.hir_crate(()).owners[id].as_ref()?;
|
||||||
let node = owner.nodes.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
|
let node = owner.node();
|
||||||
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
|
|
||||||
Some(Owner { node, node_hash: owner.nodes.node_hash })
|
Some(Owner { node, node_hash: owner.nodes.node_hash })
|
||||||
};
|
};
|
||||||
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(id).map(|i| &i.nodes);
|
providers.hir_owner_nodes = |tcx, id| tcx.hir_crate(()).owners[id].as_ref().map(|i| &i.nodes);
|
||||||
providers.hir_owner_parent = |tcx, id| {
|
providers.hir_owner_parent = |tcx, id| {
|
||||||
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.untracked_resolutions.definitions.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) = tcx.index_hir(parent_hir_id.owner).unwrap().parenting.get(&id) {
|
if let Some(local_id) =
|
||||||
|
tcx.hir_crate(()).owners[parent_hir_id.owner].as_ref().unwrap().parenting.get(&id)
|
||||||
|
{
|
||||||
parent_hir_id.local_id = *local_id;
|
parent_hir_id.local_id = *local_id;
|
||||||
}
|
}
|
||||||
parent_hir_id
|
parent_hir_id
|
||||||
|
@ -40,13 +40,6 @@ rustc_queries! {
|
|||||||
desc { "get the crate HIR" }
|
desc { "get the crate HIR" }
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
|
|
||||||
/// Avoid calling this query directly.
|
|
||||||
query index_hir(_: LocalDefId) -> Option<&'tcx crate::hir::IndexedHir<'tcx>> {
|
|
||||||
eval_always
|
|
||||||
desc { "index HIR" }
|
|
||||||
}
|
|
||||||
|
|
||||||
/// The items in a module.
|
/// The items in a module.
|
||||||
///
|
///
|
||||||
/// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
|
/// This can be conveniently accessed by `tcx.hir().visit_item_likes_in_module`.
|
||||||
@ -76,7 +69,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 crate::hir::OwnerNodes<'tcx>> {
|
query hir_owner_nodes(key: LocalDefId) -> Option<&'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()) }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user