Perform indexing during lowering.
Do not access DefId<->HirId maps before they are initialized.
This commit is contained in:
parent
c09eaea484
commit
1c7f85f17c
12 changed files with 118 additions and 170 deletions
|
@ -37,6 +37,7 @@ macro_rules! arena_types {
|
|||
[few] llvm_inline_asm: rustc_hir::LlvmInlineAsm<$tcx>,
|
||||
[] local: rustc_hir::Local<$tcx>,
|
||||
[few] mod_: rustc_hir::Mod<$tcx>,
|
||||
[] owner_info: rustc_hir::OwnerInfo<$tcx>,
|
||||
[] param: rustc_hir::Param<$tcx>,
|
||||
[] pat: rustc_hir::Pat<$tcx>,
|
||||
[] path: rustc_hir::Path<$tcx>,
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
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};
|
||||
use crate::LangItem;
|
||||
|
||||
|
@ -663,18 +663,49 @@ pub struct WhereEqPredicate<'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)]
|
||||
pub struct OwnerInfo<'hir> {
|
||||
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]>>,
|
||||
pub struct OwnerNodes<'tcx> {
|
||||
/// Pre-computed hash of the full HIR.
|
||||
pub hash: Fingerprint,
|
||||
/// Pre-computed hash of the top node.
|
||||
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
|
||||
|
@ -688,39 +719,6 @@ pub struct Crate<'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
|
||||
/// `targeted_by_break` field will be `true`) and may be `unsafe` by means of
|
||||
/// the `rules` being anything but `DefaultBlock`.
|
||||
|
|
|
@ -130,6 +130,28 @@ pub trait Map<'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.
|
||||
/// NOTE: This type is effectively only usable with `NestedVisitorMap::None`.
|
||||
pub struct ErasedMap<'hir>(&'hir dyn Map<'hir>);
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
#![feature(in_band_lifetimes)]
|
||||
#![feature(once_cell)]
|
||||
#![feature(min_specialization)]
|
||||
#![feature(never_type)]
|
||||
#![recursion_limit = "256"]
|
||||
|
||||
#[macro_use]
|
||||
|
|
|
@ -1,8 +1,8 @@
|
|||
use rustc_data_structures::stable_hasher::{HashStable, StableHasher, ToStableHashKey};
|
||||
|
||||
use crate::hir::{
|
||||
BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, TraitItem,
|
||||
TraitItemId, Ty, VisibilityKind,
|
||||
BodyId, Expr, ForeignItem, ForeignItemId, ImplItem, ImplItemId, Item, ItemId, Mod, OwnerNodes,
|
||||
TraitItem, TraitItemId, Ty, VisibilityKind,
|
||||
};
|
||||
use crate::hir_id::{HirId, ItemLocalId};
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue