Perform indexing during lowering.

Do not access DefId<->HirId maps before they are initialized.
This commit is contained in:
Camille GILLOT 2021-09-12 03:19:18 +02:00
parent c09eaea484
commit 1c7f85f17c
12 changed files with 118 additions and 170 deletions

View file

@ -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`.