Make index_hir incremental.
This commit is contained in:
parent
ed3c8e86cb
commit
c09eaea484
6 changed files with 113 additions and 140 deletions
|
@ -92,6 +92,12 @@ impl DefPathTable {
|
||||||
.iter_enumerated()
|
.iter_enumerated()
|
||||||
.map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
|
.map(move |(index, key)| (index, key, &self.def_path_hashes[index]))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn all_def_path_hashes_and_def_ids(
|
||||||
|
&self,
|
||||||
|
) -> impl Iterator<Item = (&DefPathHash, DefIndex)> + '_ {
|
||||||
|
self.def_path_hashes.iter_enumerated().map(move |(index, hash)| (hash, index))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// The definition table containing node definitions.
|
/// The definition table containing node definitions.
|
||||||
|
|
|
@ -93,10 +93,7 @@ macro_rules! arena_types {
|
||||||
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
|
[] predicates: rustc_middle::ty::PredicateInner<$tcx>,
|
||||||
|
|
||||||
// HIR query types
|
// HIR query types
|
||||||
[few] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
|
[] indexed_hir: rustc_middle::hir::IndexedHir<$tcx>,
|
||||||
[few] hir_definitions: rustc_hir::definitions::Definitions,
|
|
||||||
[] hir_owner: rustc_middle::hir::Owner<$tcx>,
|
|
||||||
[] hir_owner_nodes: rustc_middle::hir::OwnerNodes<$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
|
||||||
|
|
|
@ -1,10 +1,8 @@
|
||||||
use crate::arena::Arena;
|
|
||||||
use crate::hir::map::Map;
|
use crate::hir::map::Map;
|
||||||
use crate::hir::{IndexedHir, OwnerNodes, ParentedNode};
|
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;
|
||||||
use rustc_hir::def_id::CRATE_DEF_ID;
|
|
||||||
use rustc_hir::definitions;
|
use rustc_hir::definitions;
|
||||||
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
use rustc_hir::intravisit::{self, NestedVisitorMap, Visitor};
|
||||||
use rustc_hir::*;
|
use rustc_hir::*;
|
||||||
|
@ -17,21 +15,19 @@ use std::iter::repeat;
|
||||||
|
|
||||||
/// 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> {
|
||||||
arena: &'hir Arena<'hir>,
|
|
||||||
|
|
||||||
/// The crate
|
/// The crate
|
||||||
krate: &'hir Crate<'hir>,
|
krate: &'hir Crate<'hir>,
|
||||||
|
|
||||||
/// Source map
|
/// Source map
|
||||||
source_map: &'a SourceMap,
|
source_map: &'a SourceMap,
|
||||||
|
|
||||||
map: IndexVec<LocalDefId, Option<&'hir mut OwnerNodes<'hir>>>,
|
nodes: OwnerNodes<'hir>,
|
||||||
parenting: FxHashMap<LocalDefId, HirId>,
|
parenting: FxHashMap<LocalDefId, ItemLocalId>,
|
||||||
|
|
||||||
/// The parent of this node
|
/// The parent of this node
|
||||||
parent_node: hir::HirId,
|
parent_node: hir::ItemLocalId,
|
||||||
|
|
||||||
current_dep_node_owner: LocalDefId,
|
owner: LocalDefId,
|
||||||
|
|
||||||
definitions: &'a definitions::Definitions,
|
definitions: &'a definitions::Definitions,
|
||||||
}
|
}
|
||||||
|
@ -46,53 +42,51 @@ 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);
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
|
pub(super) fn collect<'a, 'hir: 'a>(
|
||||||
pub(super) fn root(
|
sess: &'a Session,
|
||||||
sess: &'a Session,
|
krate: &'hir Crate<'hir>,
|
||||||
arena: &'hir Arena<'hir>,
|
definitions: &'a definitions::Definitions,
|
||||||
krate: &'hir Crate<'hir>,
|
owner: LocalDefId,
|
||||||
definitions: &'a definitions::Definitions,
|
) -> Option<IndexedHir<'hir>> {
|
||||||
) -> NodeCollector<'a, 'hir> {
|
let info = krate.owners.get(owner)?.as_ref()?;
|
||||||
let mut collector = NodeCollector {
|
let item = info.node;
|
||||||
arena,
|
let mut nodes = IndexVec::new();
|
||||||
krate,
|
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: item.into() }));
|
||||||
source_map: sess.source_map(),
|
let mut collector = NodeCollector {
|
||||||
parent_node: hir::CRATE_HIR_ID,
|
krate,
|
||||||
current_dep_node_owner: CRATE_DEF_ID,
|
source_map: sess.source_map(),
|
||||||
definitions,
|
owner,
|
||||||
map: IndexVec::from_fn_n(|_| None, definitions.def_index_count()),
|
parent_node: ItemLocalId::new(0),
|
||||||
parenting: FxHashMap::default(),
|
definitions,
|
||||||
};
|
nodes: OwnerNodes {
|
||||||
collector.insert_owner(CRATE_DEF_ID, OwnerNode::Crate(krate.module()));
|
hash: info.hash,
|
||||||
|
node_hash: info.node_hash,
|
||||||
|
nodes,
|
||||||
|
bodies: &info.bodies,
|
||||||
|
},
|
||||||
|
parenting: FxHashMap::default(),
|
||||||
|
};
|
||||||
|
|
||||||
collector
|
match item {
|
||||||
}
|
OwnerNode::Crate(citem) => collector.visit_mod(&citem, citem.inner, hir::CRATE_HIR_ID),
|
||||||
|
OwnerNode::Item(item) => collector.visit_item(item),
|
||||||
|
OwnerNode::TraitItem(item) => collector.visit_trait_item(item),
|
||||||
|
OwnerNode::ImplItem(item) => collector.visit_impl_item(item),
|
||||||
|
OwnerNode::ForeignItem(item) => collector.visit_foreign_item(item),
|
||||||
|
};
|
||||||
|
|
||||||
pub(super) fn finalize_and_compute_crate_hash(self) -> IndexedHir<'hir> {
|
Some(IndexedHir { nodes: collector.nodes, parenting: collector.parenting })
|
||||||
IndexedHir { map: self.map, parenting: self.parenting }
|
}
|
||||||
}
|
|
||||||
|
|
||||||
fn insert_owner(&mut self, owner: LocalDefId, node: OwnerNode<'hir>) {
|
|
||||||
let mut nodes = IndexVec::new();
|
|
||||||
nodes.push(Some(ParentedNode { parent: ItemLocalId::new(0), node: node.into() }));
|
|
||||||
|
|
||||||
let info = self.krate.owners[owner].as_ref().unwrap();
|
|
||||||
let hash = info.hash;
|
|
||||||
let node_hash = info.node_hash;
|
|
||||||
let bodies = &info.bodies;
|
|
||||||
|
|
||||||
debug_assert!(self.map[owner].is_none());
|
|
||||||
self.map[owner] = Some(self.arena.alloc(OwnerNodes { hash, node_hash, nodes, bodies }));
|
|
||||||
}
|
|
||||||
|
|
||||||
|
impl<'a, 'hir> NodeCollector<'a, 'hir> {
|
||||||
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
|
fn insert(&mut self, span: Span, hir_id: HirId, node: Node<'hir>) {
|
||||||
debug_assert_eq!(self.current_dep_node_owner, hir_id.owner);
|
debug_assert_eq!(self.owner, hir_id.owner);
|
||||||
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
|
debug_assert_ne!(hir_id.local_id.as_u32(), 0);
|
||||||
|
|
||||||
// Make sure that the DepNode of some node coincides with the HirId
|
// Make sure that the DepNode of some node coincides with the HirId
|
||||||
// owner of that node.
|
// owner of that node.
|
||||||
if cfg!(debug_assertions) {
|
if cfg!(debug_assertions) {
|
||||||
if hir_id.owner != self.current_dep_node_owner {
|
if hir_id.owner != self.owner {
|
||||||
let node_str = match self.definitions.opt_hir_id_to_local_def_id(hir_id) {
|
let node_str = match self.definitions.opt_hir_id_to_local_def_id(hir_id) {
|
||||||
Some(def_id) => self.definitions.def_path(def_id).to_string_no_crate_verbose(),
|
Some(def_id) => self.definitions.def_path(def_id).to_string_no_crate_verbose(),
|
||||||
None => format!("{:?}", node),
|
None => format!("{:?}", node),
|
||||||
|
@ -104,62 +98,41 @@ impl<'a, 'hir: 'a> NodeCollector<'a, 'hir> {
|
||||||
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_str,
|
||||||
self.definitions
|
self.definitions.def_path(self.owner).to_string_no_crate_verbose(),
|
||||||
.def_path(self.current_dep_node_owner)
|
self.owner,
|
||||||
.to_string_no_crate_verbose(),
|
|
||||||
self.current_dep_node_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(),
|
||||||
hir_id.owner,
|
hir_id.owner,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
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(
|
insert_vec_map(
|
||||||
&mut nodes.nodes,
|
&mut self.nodes.nodes,
|
||||||
hir_id.local_id,
|
hir_id.local_id,
|
||||||
ParentedNode { parent: self.parent_node.local_id, node: node },
|
ParentedNode { parent: self.parent_node, node: node },
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
|
fn with_parent<F: FnOnce(&mut Self)>(&mut self, parent_node_id: HirId, f: F) {
|
||||||
|
debug_assert_eq!(parent_node_id.owner, self.owner);
|
||||||
let parent_node = self.parent_node;
|
let parent_node = self.parent_node;
|
||||||
self.parent_node = parent_node_id;
|
self.parent_node = parent_node_id.local_id;
|
||||||
f(self);
|
f(self);
|
||||||
self.parent_node = parent_node;
|
self.parent_node = parent_node;
|
||||||
}
|
}
|
||||||
|
|
||||||
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 prev_parent = self.parent_node;
|
|
||||||
|
|
||||||
self.current_dep_node_owner = dep_node_owner;
|
|
||||||
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) {
|
fn insert_nested(&mut self, item: LocalDefId) {
|
||||||
#[cfg(debug_assertions)]
|
let dk_parent = self.definitions.def_key(item).parent.unwrap();
|
||||||
{
|
let dk_parent = LocalDefId { local_def_index: dk_parent };
|
||||||
let dk_parent = self.definitions.def_key(item).parent.unwrap();
|
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
|
||||||
let dk_parent = LocalDefId { local_def_index: dk_parent };
|
debug_assert_eq!(dk_parent.owner, self.owner, "Different parents for {:?}", item);
|
||||||
let dk_parent = self.definitions.local_def_id_to_hir_id(dk_parent);
|
if dk_parent.local_id != self.parent_node {
|
||||||
debug_assert_eq!(
|
self.parenting.insert(item, self.parent_node);
|
||||||
dk_parent.owner, self.parent_node.owner,
|
|
||||||
"Different parents for {:?}",
|
|
||||||
item
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(self.parenting.insert(item, self.parent_node), None);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
impl<'a, 'hir> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
type Map = Map<'hir>;
|
type Map = Map<'hir>;
|
||||||
|
|
||||||
/// Because we want to track parent items and so forth, enable
|
/// Because we want to track parent items and so forth, enable
|
||||||
|
@ -173,26 +146,24 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
fn visit_nested_item(&mut self, item: ItemId) {
|
fn visit_nested_item(&mut self, item: ItemId) {
|
||||||
debug!("visit_nested_item: {:?}", item);
|
debug!("visit_nested_item: {:?}", item);
|
||||||
self.insert_nested(item.def_id);
|
self.insert_nested(item.def_id);
|
||||||
self.visit_item(self.krate.item(item));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
|
fn visit_nested_trait_item(&mut self, item_id: TraitItemId) {
|
||||||
self.insert_nested(item_id.def_id);
|
self.insert_nested(item_id.def_id);
|
||||||
self.visit_trait_item(self.krate.trait_item(item_id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
|
fn visit_nested_impl_item(&mut self, item_id: ImplItemId) {
|
||||||
self.insert_nested(item_id.def_id);
|
self.insert_nested(item_id.def_id);
|
||||||
self.visit_impl_item(self.krate.impl_item(item_id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
|
fn visit_nested_foreign_item(&mut self, foreign_id: ForeignItemId) {
|
||||||
self.insert_nested(foreign_id.def_id);
|
self.insert_nested(foreign_id.def_id);
|
||||||
self.visit_foreign_item(self.krate.foreign_item(foreign_id));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_nested_body(&mut self, id: BodyId) {
|
fn visit_nested_body(&mut self, id: BodyId) {
|
||||||
self.visit_body(self.krate.body(id));
|
let body = self.krate.body(id);
|
||||||
|
debug_assert_eq!(id.hir_id.owner, self.owner);
|
||||||
|
self.visit_body(body);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_param(&mut self, param: &'hir Param<'hir>) {
|
fn visit_param(&mut self, param: &'hir Param<'hir>) {
|
||||||
|
@ -205,8 +176,8 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
|
|
||||||
fn visit_item(&mut self, i: &'hir Item<'hir>) {
|
fn visit_item(&mut self, i: &'hir Item<'hir>) {
|
||||||
debug!("visit_item: {:?}", i);
|
debug!("visit_item: {:?}", i);
|
||||||
self.insert_owner(i.def_id, OwnerNode::Item(i));
|
debug_assert_eq!(i.def_id, self.owner);
|
||||||
self.with_dep_node_owner(i.def_id, |this| {
|
self.with_parent(i.hir_id(), |this| {
|
||||||
if let ItemKind::Struct(ref struct_def, _) = i.kind {
|
if let ItemKind::Struct(ref struct_def, _) = i.kind {
|
||||||
// If this is a tuple or unit-like struct, register the constructor.
|
// If this is a tuple or unit-like struct, register the constructor.
|
||||||
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
|
if let Some(ctor_hir_id) = struct_def.ctor_hir_id() {
|
||||||
|
@ -218,8 +189,8 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
|
fn visit_foreign_item(&mut self, fi: &'hir ForeignItem<'hir>) {
|
||||||
self.insert_owner(fi.def_id, OwnerNode::ForeignItem(fi));
|
debug_assert_eq!(fi.def_id, self.owner);
|
||||||
self.with_dep_node_owner(fi.def_id, |this| {
|
self.with_parent(fi.hir_id(), |this| {
|
||||||
intravisit::walk_foreign_item(this, fi);
|
intravisit::walk_foreign_item(this, fi);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -236,15 +207,15 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
|
fn visit_trait_item(&mut self, ti: &'hir TraitItem<'hir>) {
|
||||||
self.insert_owner(ti.def_id, OwnerNode::TraitItem(ti));
|
debug_assert_eq!(ti.def_id, self.owner);
|
||||||
self.with_dep_node_owner(ti.def_id, |this| {
|
self.with_parent(ti.hir_id(), |this| {
|
||||||
intravisit::walk_trait_item(this, ti);
|
intravisit::walk_trait_item(this, ti);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
|
fn visit_impl_item(&mut self, ii: &'hir ImplItem<'hir>) {
|
||||||
self.insert_owner(ii.def_id, OwnerNode::ImplItem(ii));
|
debug_assert_eq!(ii.def_id, self.owner);
|
||||||
self.with_dep_node_owner(ii.def_id, |this| {
|
self.with_parent(ii.hir_id(), |this| {
|
||||||
intravisit::walk_impl_item(this, ii);
|
intravisit::walk_impl_item(this, ii);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -332,7 +303,8 @@ impl<'a, 'hir: 'a> Visitor<'hir> for NodeCollector<'a, 'hir> {
|
||||||
s: Span,
|
s: Span,
|
||||||
id: HirId,
|
id: HirId,
|
||||||
) {
|
) {
|
||||||
assert_eq!(self.parent_node, id);
|
assert_eq!(self.owner, id.owner);
|
||||||
|
assert_eq!(self.parent_node, id.local_id);
|
||||||
intravisit::walk_fn(self, fk, fd, b, s, id);
|
intravisit::walk_fn(self, fk, fd, b, s, id);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,3 @@
|
||||||
use self::collector::NodeCollector;
|
|
||||||
|
|
||||||
use crate::hir::{IndexedHir, ModuleItems, Owner};
|
use crate::hir::{IndexedHir, ModuleItems, Owner};
|
||||||
use crate::ty::TyCtxt;
|
use crate::ty::TyCtxt;
|
||||||
use rustc_ast as ast;
|
use rustc_ast as ast;
|
||||||
|
@ -318,7 +316,7 @@ impl<'hir> Map<'hir> {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn get_parent_node(&self, hir_id: HirId) -> HirId {
|
pub fn get_parent_node(&self, hir_id: HirId) -> HirId {
|
||||||
self.find_parent_node(hir_id).unwrap_or(CRATE_HIR_ID)
|
self.find_parent_node(hir_id).unwrap()
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
|
/// Retrieves the `Node` corresponding to `id`, returning `None` if cannot be found.
|
||||||
|
@ -1067,36 +1065,30 @@ impl<'hir> intravisit::Map<'hir> for Map<'hir> {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn index_hir<'tcx>(tcx: TyCtxt<'tcx>, (): ()) -> &'tcx IndexedHir<'tcx> {
|
pub(super) fn index_hir<'tcx>(
|
||||||
let _prof_timer = tcx.sess.prof.generic_activity("build_hir_map");
|
tcx: TyCtxt<'tcx>,
|
||||||
|
owner: LocalDefId,
|
||||||
// We can access untracked state since we are an eval_always query.
|
) -> Option<&'tcx IndexedHir<'tcx>> {
|
||||||
let mut collector = NodeCollector::root(
|
let map = collector::collect(
|
||||||
tcx.sess,
|
tcx.sess,
|
||||||
&**tcx.arena,
|
|
||||||
tcx.untracked_crate,
|
tcx.untracked_crate,
|
||||||
&tcx.untracked_resolutions.definitions,
|
&tcx.untracked_resolutions.definitions,
|
||||||
);
|
owner,
|
||||||
let top_mod = tcx.untracked_crate.module();
|
)?;
|
||||||
collector.visit_mod(top_mod, top_mod.inner, CRATE_HIR_ID);
|
|
||||||
|
|
||||||
let map = collector.finalize_and_compute_crate_hash();
|
Some(&*tcx.arena.alloc(map))
|
||||||
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 {
|
||||||
assert_eq!(crate_num, LOCAL_CRATE);
|
debug_assert_eq!(crate_num, LOCAL_CRATE);
|
||||||
|
|
||||||
// We can access untracked state since we are an eval_always query.
|
|
||||||
let mut hcx = tcx.create_stable_hashing_context();
|
|
||||||
|
|
||||||
let mut hir_body_nodes: Vec<_> = tcx
|
let mut hir_body_nodes: Vec<_> = tcx
|
||||||
.index_hir(())
|
.untracked_resolutions
|
||||||
.map
|
.definitions
|
||||||
.iter_enumerated()
|
.def_path_table()
|
||||||
.filter_map(|(def_id, hod)| {
|
.all_def_path_hashes_and_def_ids()
|
||||||
let def_path_hash = tcx.untracked_resolutions.definitions.def_path_hash(def_id);
|
.filter_map(|(def_path_hash, local_def_index)| {
|
||||||
let hash = hod.as_ref()?.hash;
|
let def_id = LocalDefId { local_def_index };
|
||||||
|
let hash = tcx.index_hir(def_id).as_ref()?.nodes.hash;
|
||||||
Some((def_path_hash, hash, def_id))
|
Some((def_path_hash, hash, def_id))
|
||||||
})
|
})
|
||||||
.collect();
|
.collect();
|
||||||
|
@ -1120,6 +1112,7 @@ pub(super) fn crate_hash(tcx: TyCtxt<'_>, crate_num: CrateNum) -> Svh {
|
||||||
|
|
||||||
source_file_names.sort_unstable();
|
source_file_names.sort_unstable();
|
||||||
|
|
||||||
|
let mut hcx = tcx.create_stable_hashing_context();
|
||||||
let mut stable_hasher = StableHasher::new();
|
let mut stable_hasher = StableHasher::new();
|
||||||
for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
|
for (def_path_hash, fingerprint, def_id) in hir_body_nodes.iter() {
|
||||||
def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);
|
def_path_hash.0.hash_stable(&mut hcx, &mut stable_hasher);
|
||||||
|
|
|
@ -19,16 +19,13 @@ 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.
|
/// Result of HIR indexing for a given HIR owner.
|
||||||
#[derive(Debug)]
|
#[derive(Debug, HashStable)]
|
||||||
pub struct IndexedHir<'hir> {
|
pub struct IndexedHir<'hir> {
|
||||||
/// Contents of the HIR owned by each definition. None for definitions that are not HIR owners.
|
/// Contents of the HIR.
|
||||||
// The `mut` comes from construction time, and is harmless since we only ever hand out
|
nodes: OwnerNodes<'hir>,
|
||||||
// immutable refs to IndexedHir.
|
/// Map from each nested owner to its parent's local id.
|
||||||
map: IndexVec<LocalDefId, Option<&'hir mut OwnerNodes<'hir>>>,
|
parenting: FxHashMap<LocalDefId, ItemLocalId>,
|
||||||
/// Map from each owner to its parent's HirId inside another owner.
|
|
||||||
// This map is separate from `map` to eventually allow for per-owner indexing.
|
|
||||||
parenting: FxHashMap<LocalDefId, HirId>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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
|
||||||
|
@ -132,15 +129,24 @@ 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.index_hir(()).map[id].as_ref()?;
|
let owner = tcx.index_hir(id)?;
|
||||||
let node = owner.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
|
let node = owner.nodes.nodes[ItemLocalId::new(0)].as_ref().unwrap().node;
|
||||||
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
|
let node = node.as_owner().unwrap(); // Indexing must ensure it is an OwnerNode.
|
||||||
Some(Owner { node, node_hash: owner.node_hash })
|
Some(Owner { node, node_hash: owner.nodes.node_hash })
|
||||||
};
|
};
|
||||||
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(()).map[id].as_deref();
|
providers.hir_owner_nodes = |tcx, id| tcx.index_hir(id).map(|i| &i.nodes);
|
||||||
providers.hir_owner_parent = |tcx, id| {
|
providers.hir_owner_parent = |tcx, id| {
|
||||||
let index = tcx.index_hir(());
|
let parent = tcx.untracked_resolutions.definitions.def_key(id).parent;
|
||||||
index.parenting.get(&id).copied().unwrap_or(CRATE_HIR_ID)
|
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);
|
||||||
|
if let Some(local_id) = tcx.index_hir(parent_hir_id.owner).unwrap().parenting.get(&id) {
|
||||||
|
parent_hir_id.local_id = *local_id;
|
||||||
|
}
|
||||||
|
parent_hir_id
|
||||||
|
});
|
||||||
|
parent
|
||||||
};
|
};
|
||||||
providers.hir_attrs = |tcx, id| AttributeMap::new(&tcx.hir_crate(()).owners[id]);
|
providers.hir_attrs = |tcx, id| AttributeMap::new(&tcx.hir_crate(()).owners[id]);
|
||||||
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);
|
||||||
|
|
|
@ -42,9 +42,8 @@ rustc_queries! {
|
||||||
|
|
||||||
/// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
|
/// The indexed HIR. This can be conveniently accessed by `tcx.hir()`.
|
||||||
/// Avoid calling this query directly.
|
/// Avoid calling this query directly.
|
||||||
query index_hir(_: ()) -> &'tcx crate::hir::IndexedHir<'tcx> {
|
query index_hir(_: LocalDefId) -> Option<&'tcx crate::hir::IndexedHir<'tcx>> {
|
||||||
eval_always
|
eval_always
|
||||||
no_hash
|
|
||||||
desc { "index HIR" }
|
desc { "index HIR" }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue