diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 6f51e05881be5..8da51cfca94c2 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -392,14 +392,18 @@ impl<'a> LoweringContext<'a> { match tree.kind { UseTreeKind::Simple(_, id1, id2) => { for &id in &[id1, id2] { - self.lctx.resolver.definitions().create_def_with_parent( + let def_index = self.lctx.resolver.definitions().create_def_with_parent( owner, id, + None, DefPathData::Misc, ExpnId::root(), tree.prefix.span, ); - self.lctx.allocate_hir_id_counter(id); + let hir_id = self.lctx.allocate_hir_id_counter(id); + + self.lctx.resolver.definitions() + .hir_to_def_index.insert(hir_id, def_index); } } UseTreeKind::Glob => (), @@ -534,6 +538,10 @@ impl<'a> LoweringContext<'a> { .definitions() .init_node_id_to_hir_id_mapping(self.node_id_to_hir_id); + self.resolver + .definitions() + .finalize_hir_to_def_index_mapping(); + hir::Crate { module, attrs, @@ -793,17 +801,20 @@ impl<'a> LoweringContext<'a> { ), }; + let hir_id = self.lower_node_id(node_id); + // Add a definition for the in-band lifetime def. self.resolver.definitions().create_def_with_parent( parent_index, node_id, + Some(hir_id), DefPathData::LifetimeNs(str_name), ExpnId::root(), span, ); hir::GenericParam { - hir_id: self.lower_node_id(node_id), + hir_id, name: hir_name, attrs: hir_vec![], bounds: hir_vec![], @@ -1095,6 +1106,7 @@ impl<'a> LoweringContext<'a> { self.resolver.definitions().create_def_with_parent( parent_def_index, impl_trait_node_id, + None, DefPathData::ImplTrait, ExpnId::root(), constraint.span, @@ -1576,6 +1588,7 @@ impl<'a> LoweringContext<'a> { self.context.resolver.definitions().create_def_with_parent( self.parent, def_node_id, + Some(hir_id), DefPathData::LifetimeNs(name.ident().as_interned_str()), ExpnId::root(), lifetime.span); diff --git a/src/librustc/hir/map/def_collector.rs b/src/librustc/hir/map/def_collector.rs index 1997e2aab35e8..2391689db9292 100644 --- a/src/librustc/hir/map/def_collector.rs +++ b/src/librustc/hir/map/def_collector.rs @@ -28,7 +28,8 @@ impl<'a> DefCollector<'a> { -> DefIndex { let parent_def = self.parent_def; debug!("create_def(node_id={:?}, data={:?}, parent_def={:?})", node_id, data, parent_def); - self.definitions.create_def_with_parent(parent_def, node_id, data, self.expansion, span) + self.definitions.create_def_with_parent( + parent_def, node_id, None, data, self.expansion, span) } fn with_parent(&mut self, parent_def: DefIndex, f: F) { diff --git a/src/librustc/hir/map/definitions.rs b/src/librustc/hir/map/definitions.rs index 187bc59332460..ebb6119811f7b 100644 --- a/src/librustc/hir/map/definitions.rs +++ b/src/librustc/hir/map/definitions.rs @@ -8,7 +8,7 @@ use crate::hir; use crate::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE, CRATE_DEF_INDEX}; use crate::ich::Fingerprint; use crate::session::CrateDisambiguator; -use crate::util::nodemap::NodeMap; +use crate::util::nodemap::{HirIdMap, NodeMap}; use rustc_data_structures::fx::FxHashMap; use rustc_data_structures::indexed_vec::{IndexVec}; @@ -16,6 +16,7 @@ use rustc_data_structures::stable_hasher::StableHasher; use std::borrow::Borrow; use std::fmt::Write; use std::hash::Hash; +use std::mem; use syntax::ast; use syntax::ext::hygiene::ExpnId; use syntax::symbol::{Symbol, sym, InternedString}; @@ -92,6 +93,10 @@ impl DefPathTable { pub struct Definitions { table: DefPathTable, node_to_def_index: NodeMap, + pub hir_to_def_index: HirIdMap, + /// `DefIndex`es created by `DefCollector::create_def` before the AST lowering; used + /// to complete the `hir_to_def_index` mapping afterwards. + defs_awaiting_hir_id: NodeMap, def_index_to_node: Vec, pub(super) node_to_hir_id: IndexVec, /// If `ExpnId` is an ID of some macro expansion, @@ -360,11 +365,21 @@ impl Definitions { self.node_to_def_index.get(&node).cloned() } + #[inline] + pub fn opt_def_index_from_hir_id(&self, hir: hir::HirId) -> Option { + self.hir_to_def_index.get(&hir).cloned() + } + #[inline] pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { self.opt_def_index(node).map(DefId::local) } + #[inline] + pub fn opt_local_def_id_from_hir_id(&self, hir: hir::HirId) -> Option { + self.opt_def_index_from_hir_id(hir).map(DefId::local) + } + #[inline] pub fn local_def_id(&self, node: ast::NodeId) -> DefId { self.opt_local_def_id(node).unwrap() @@ -440,6 +455,7 @@ impl Definitions { assert!(self.def_index_to_node.is_empty()); self.def_index_to_node.push(ast::CRATE_NODE_ID); self.node_to_def_index.insert(ast::CRATE_NODE_ID, root_index); + self.hir_to_def_index.insert(hir::CRATE_HIR_ID, root_index); self.set_invocation_parent(ExpnId::root(), root_index); // Allocate some other `DefIndex`es that always must exist. @@ -452,6 +468,7 @@ impl Definitions { pub fn create_def_with_parent(&mut self, parent: DefIndex, node_id: ast::NodeId, + hir_id: Option, data: DefPathData, expn_id: ExpnId, span: Span) @@ -499,6 +516,12 @@ impl Definitions { if node_id != ast::DUMMY_NODE_ID { debug!("create_def_with_parent: def_index_to_node[{:?} <-> {:?}", index, node_id); self.node_to_def_index.insert(node_id, index); + + if let Some(hir_id) = hir_id { + self.hir_to_def_index.insert(hir_id, index); + } else { + self.defs_awaiting_hir_id.insert(node_id, index); + } } if expn_id != ExpnId::root() { @@ -522,6 +545,15 @@ impl Definitions { self.node_to_hir_id = mapping; } + /// Fill the missing bits of the `HirId` to `DefIndex` mapping after the AST lowering; see + /// the related comment to the `defs_awaiting_hir_id` map in the `Definitions` struct. + pub fn finalize_hir_to_def_index_mapping(&mut self) { + for (node_id, def_id) in mem::replace(&mut self.defs_awaiting_hir_id, Default::default()) { + let hir_id = self.node_to_hir_id[node_id]; + self.hir_to_def_index.insert(hir_id, def_id); + } + } + pub fn expansion_that_defined(&self, index: DefIndex) -> ExpnId { self.expansions_that_defined.get(&index).cloned().unwrap_or(ExpnId::root()) } @@ -611,6 +643,7 @@ macro_rules! define_global_metadata_kind { definitions.create_def_with_parent( CRATE_DEF_INDEX, ast::DUMMY_NODE_ID, + Some(hir::DUMMY_HIR_ID), DefPathData::GlobalMetaData(instance.name().as_interned_str()), ExpnId::root(), DUMMY_SP diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index 42a4a9909f8a9..fb965490523bb 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -281,8 +281,7 @@ impl<'hir> Map<'hir> { #[inline] pub fn opt_local_def_id(&self, hir_id: HirId) -> Option { - let node_id = self.hir_to_node_id(hir_id); - self.definitions.opt_local_def_id(node_id) + self.definitions.opt_local_def_id_from_hir_id(hir_id) } #[inline]