let mut data = vec![];
let mut index = Some(start_index);
loop {
+ debug!("DefPath::make: krate={:?} index={:?}", krate, index);
let p = index.unwrap();
let key = get_key(p);
+ debug!("DefPath::make: key={:?}", key);
match key.disambiguated_data.data {
DefPathData::CrateRoot => {
assert!(key.parent.is_none());
self.data[index.as_usize()].key.clone()
}
+ pub fn def_index_for_def_key(&self, key: DefKey) -> Option<DefIndex> {
+ self.key_map.get(&key).cloned()
+ }
+
/// Returns the path from the crate root to `index`. The root
/// nodes are not included in the path (i.e., this will be an
/// empty vector for the crate root). For an inlined item, this
}
}
- pub fn retrace_path(&self, path: &DefPath) -> Option<DefIndex> {
- debug!("retrace_path(path={:?})", path);
-
- // we assume that we only want to retrace paths relative to
- // the crate root
- assert!(path.is_local());
-
- let root_key = DefKey {
- parent: None,
- disambiguated_data: DisambiguatedDefPathData {
- data: DefPathData::CrateRoot,
- disambiguator: 0,
- },
- };
- let root_id = self.key_map[&root_key];
-
- debug!("retrace_path: root_id={:?}", root_id);
-
- let mut id = root_id;
- for data in &path.data {
- let key = DefKey { parent: Some(id), disambiguated_data: data.clone() };
- debug!("key = {:?}", key);
- id = match self.key_map.get(&key) {
- Some(&id) => id,
- None => return None
- };
- }
-
- Some(id)
- }
-
pub fn create_def_with_parent(&mut self,
parent: Option<DefIndex>,
node_id: ast::NodeId,
use middle::cstore::InlinedItem;
use middle::cstore::InlinedItem as II;
-use hir::def_id::{CRATE_DEF_INDEX, DefId};
+use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
use syntax::abi::Abi;
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, };
self.definitions.borrow().def_path(def_id.index)
}
- pub fn retrace_path(&self, path: &DefPath) -> Option<DefId> {
- self.definitions.borrow().retrace_path(path)
- .map(DefId::local)
+ pub fn def_index_for_def_key(&self, def_key: DefKey) -> Option<DefIndex> {
+ self.definitions.borrow().def_index_for_def_key(def_key)
}
pub fn local_def_id(&self, node: NodeId) -> DefId {
// are *mostly* used as a part of that interface, but these should
// probably get a better home if someone can find one.
-use hir::svh::Svh;
-use hir::map as hir_map;
use hir::def::{self, Def};
+use hir::def_id::{DefId, DefIndex};
+use hir::map as hir_map;
+use hir::map::definitions::DefKey;
+use hir::svh::Svh;
use middle::lang_items;
use ty::{self, Ty, TyCtxt, VariantKind};
-use hir::def_id::{DefId, DefIndex};
use mir::repr::Mir;
use mir::mir_map::MirMap;
use session::Session;
fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>;
// resolve
+ fn def_index_for_def_key(&self,
+ cnum: ast::CrateNum,
+ def: DefKey)
+ -> Option<DefIndex>;
fn def_key(&self, def: DefId) -> hir_map::DefKey;
fn relative_def_path(&self, def: DefId) -> hir_map::DefPath;
fn variant_kind(&self, def_id: DefId) -> Option<VariantKind>;
-> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
fn trait_item_def_ids(&self, def: DefId)
-> Vec<ty::ImplOrTraitItemId> { bug!("trait_item_def_ids") }
+ fn def_index_for_def_key(&self,
+ cnum: ast::CrateNum,
+ def: DefKey)
+ -> Option<DefIndex> {
+ None
+ }
// impl info
fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>
//! type context book-keeping
use dep_graph::{DepGraph, DepTrackingMap};
-use hir::map as ast_map;
use session::Session;
use lint;
use middle;
use middle::cstore::LOCAL_CRATE;
use hir::def::DefMap;
-use hir::def_id::DefId;
+use hir::def_id::{DefId, DefIndex};
+use hir::map as ast_map;
+use hir::map::{DefKey, DefPath, DefPathData, DisambiguatedDefPathData};
use middle::free_region::FreeRegionMap;
use middle::region::RegionMaps;
use middle::resolve_lifetime;
}
}
+ /// Given a def-key `key` and a crate `krate`, finds the def-index
+ /// that `krate` assigned to `key`. This `DefIndex` will always be
+ /// relative to `krate`.
+ ///
+ /// Returns `None` if there is no `DefIndex` with that key.
+ pub fn def_index_for_def_key(self, krate: ast::CrateNum, key: DefKey)
+ -> Option<DefIndex> {
+ if krate == LOCAL_CRATE {
+ self.map.def_index_for_def_key(key)
+ } else {
+ self.sess.cstore.def_index_for_def_key(krate, key)
+ }
+ }
+
+ pub fn retrace_path(self, path: &DefPath) -> Option<DefId> {
+ debug!("retrace_path(path={:?})", path);
+
+ let root_key = DefKey {
+ parent: None,
+ disambiguated_data: DisambiguatedDefPathData {
+ data: DefPathData::CrateRoot,
+ disambiguator: 0,
+ },
+ };
+
+ let root_index = self.def_index_for_def_key(path.krate, root_key)
+ .expect("no root key?");
+
+ debug!("retrace_path: root_index={:?}", root_index);
+
+ let mut index = root_index;
+ for data in &path.data {
+ let key = DefKey { parent: Some(index), disambiguated_data: data.clone() };
+ debug!("retrace_path: key={:?}", key);
+ match self.def_index_for_def_key(path.krate, key) {
+ Some(i) => index = i,
+ None => return None,
+ }
+ }
+
+ Some(DefId { krate: path.krate, index: index })
+ }
+
pub fn type_parameter_def(self,
node_id: NodeId)
-> ty::TypeParameterDef<'tcx>
pub fn retrace(&self, tcx: TyCtxt) -> RetracedDefIdDirectory {
let ids = self.paths.iter()
- .map(|path| tcx.map.retrace_path(path))
+ .map(|path| tcx.retrace_path(path))
.collect();
RetracedDefIdDirectory { ids: ids }
}
extern_crate: Cell::new(None),
index: decoder::load_index(metadata.as_slice()),
xref_index: decoder::load_xrefs(metadata.as_slice()),
+ key_map: decoder::load_key_map(metadata.as_slice()),
data: metadata,
cnum_map: RefCell::new(cnum_map),
cnum: cnum,
use rustc::dep_graph::DepNode;
use rustc::hir::map as hir_map;
+use rustc::hir::map::DefKey;
use rustc::mir::repr::Mir;
use rustc::mir::mir_map::MirMap;
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
decoder::get_reachable_ids(&cdata)
}
+ fn def_index_for_def_key(&self,
+ cnum: ast::CrateNum,
+ def: DefKey)
+ -> Option<DefIndex> {
+ let cdata = self.get_crate_data(cnum);
+ cdata.key_map.get(&def).cloned()
+ }
+
/// Returns the `DefKey` for a given `DefId`. This indicates the
/// parent `DefId` as well as some idea of what kind of data the
/// `DefId` refers to.
use loader;
use rustc::dep_graph::DepGraph;
-use rustc::hir::def_id::DefId;
+use rustc::hir::def_id::{DefIndex, DefId};
+use rustc::hir::map::DefKey;
use rustc::hir::svh::Svh;
use rustc::middle::cstore::{ExternCrate};
use rustc::session::config::PanicStrategy;
pub index: index::Index,
pub xref_index: index::DenseIndex,
+ /// For each public item in this crate, we encode a key. When the
+ /// crate is loaded, we read all the keys and put them in this
+ /// hashmap, which gives the reverse mapping. This allows us to
+ /// quickly retrace a `DefPath`, which is needed for incremental
+ /// compilation support.
+ pub key_map: FnvHashMap<DefKey, DefIndex>,
+
/// Flag if this crate is required by an rlib version of this crate, or in
/// other words whether it was explicitly linked to. An example of a crate
/// where this is false is when an allocator crate is injected into the
use rustc::hir::svh::Svh;
use rustc::hir::map as hir_map;
+use rustc::hir::map::DefKey;
use rustc::util::nodemap::FnvHashMap;
use rustc::hir;
use rustc::session::config::PanicStrategy;
index::DenseIndex::from_buf(index.data, index.start, index.end)
}
+// Go through each item in the metadata and create a map from that
+// item's def-key to the item's DefIndex.
+pub fn load_key_map(data: &[u8]) -> FnvHashMap<DefKey, DefIndex> {
+ let root_doc = rbml::Doc::new(data);
+ let items_doc = reader::get_doc(root_doc, tag_items);
+ let items_data_doc = reader::get_doc(items_doc, tag_items_data);
+ reader::docs(items_data_doc)
+ .filter(|&(tag, _)| tag == tag_items_data_item)
+ .map(|(_, item_doc)| {
+ // load def-key from item
+ let key = item_def_key(item_doc);
+
+ // load def-index from item; we only encode the full def-id,
+ // so just pull out the index
+ let def_id_doc = reader::get_doc(item_doc, tag_def_id);
+ let def_id = untranslated_def_id(def_id_doc);
+ assert!(def_id.is_local()); // local to the crate we are decoding, that is
+
+ (key, def_id.index)
+ })
+ .collect()
+}
+
#[derive(Clone, Copy, Debug, PartialEq)]
enum Family {
ImmStatic, // c
reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string()
}
-fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
+fn untranslated_def_id(d: rbml::Doc) -> DefId {
let id = reader::doc_as_u64(d);
let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
- let def_id = DefId { krate: (id >> 32) as u32, index: index };
+ DefId { krate: (id >> 32) as u32, index: index }
+}
+
+fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
+ let def_id = untranslated_def_id(d);
translate_def_id(cdata, def_id)
}
pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey {
debug!("def_key: id={:?}", id);
let item_doc = cdata.lookup_item(id);
+ item_def_key(item_doc)
+}
+
+fn item_def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
match reader::maybe_get_doc(item_doc, tag_def_key) {
Some(def_key_doc) => {
let mut decoder = reader::Decoder::new(def_key_doc);