diff --git a/src/librustc/hir/map/collector.rs b/src/librustc/hir/map/collector.rs index ee5192f58c2..a33ccf1b970 100644 --- a/src/librustc/hir/map/collector.rs +++ b/src/librustc/hir/map/collector.rs @@ -203,12 +203,22 @@ impl<'a, 'hir> NodeCollector<'a, 'hir> { let owner = HirOwner { parent: entry.parent, node: entry.node }; let arena = self.arena; + let krate = self.krate; let items = self.owner_items_map.entry(id.owner).or_insert_with(|| { - arena.alloc(HirOwnerItems { items: IndexVec::new(), bodies: FxHashMap::default() }) + arena.alloc(HirOwnerItems { + // Insert a dummy node which will be overwritten + // when we call `insert_entry` on the HIR owner. + owner: Node::Crate(&krate.item), + items: IndexVec::new(), + bodies: FxHashMap::default(), + }) }); if i == 0 { + // Overwrite the dummy node with the real HIR owner. + items.owner = entry.node; + self.owner_map.insert(id.owner, self.arena.alloc(owner)); // FIXME: feature(impl_trait_in_bindings) broken and trigger this assert //assert!(self.owner_map.insert(id.owner, self.arena.alloc(owner)).is_none()); diff --git a/src/librustc/hir/mod.rs b/src/librustc/hir/mod.rs index 590ad1b6995..edb52666923 100644 --- a/src/librustc/hir/mod.rs +++ b/src/librustc/hir/mod.rs @@ -5,10 +5,12 @@ pub mod exports; pub mod map; +use crate::ich::StableHashingContext; use crate::ty::query::Providers; use crate::ty::TyCtxt; use rustc_data_structures::cold_path; use rustc_data_structures::fx::FxHashMap; +use rustc_data_structures::stable_hasher::{HashStable, StableHasher}; use rustc_hir::def_id::{DefId, LOCAL_CRATE}; use rustc_hir::print; use rustc_hir::Body; @@ -25,19 +27,39 @@ pub struct HirOwner<'tcx> { node: Node<'tcx>, } -#[derive(HashStable, Clone)] +#[derive(Clone)] pub struct HirItem<'tcx> { parent: ItemLocalId, node: Node<'tcx>, } -#[derive(HashStable)] +impl<'a, 'tcx> HashStable> for HirItem<'tcx> { + fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { + let HirItem { parent, node } = self; + hcx.while_hashing_hir_bodies(false, |hcx| { + parent.hash_stable(hcx, hasher); + node.hash_stable(hcx, hasher); + }); + } +} + pub struct HirOwnerItems<'tcx> { - //owner: &'tcx HirOwner<'tcx>, + owner: Node<'tcx>, items: IndexVec>>, bodies: FxHashMap>, } +impl<'a, 'tcx> HashStable> for HirOwnerItems<'tcx> { + fn hash_stable(&self, hcx: &mut StableHashingContext<'a>, hasher: &mut StableHasher) { + // We ignore the `items` and `bodies` fields since these refer to information reachable + // when hashing `owner` with its bodies. + let HirOwnerItems { owner, items: _, bodies: _ } = *self; + hcx.while_hashing_hir_bodies(true, |hcx| { + owner.hash_stable(hcx, hasher); + }); + } +} + /// A wrapper type which allows you to access HIR. #[derive(Clone)] pub struct Hir<'tcx> {