Skip to content

Commit b01919a

Browse files
committed
allow retracing paths across crates
For external crates, we must build up a map that goes from the DefKey to the DefIndex. We do this by iterating over each index that is found in the metadata and loading the associated DefKey.
1 parent 303fdc1 commit b01919a

File tree

9 files changed

+123
-44
lines changed

9 files changed

+123
-44
lines changed

src/librustc/hir/map/definitions.rs

Lines changed: 6 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -82,8 +82,10 @@ impl DefPath {
8282
let mut data = vec![];
8383
let mut index = Some(start_index);
8484
loop {
85+
debug!("DefPath::make: krate={:?} index={:?}", krate, index);
8586
let p = index.unwrap();
8687
let key = get_key(p);
88+
debug!("DefPath::make: key={:?}", key);
8789
match key.disambiguated_data.data {
8890
DefPathData::CrateRoot => {
8991
assert!(key.parent.is_none());
@@ -178,6 +180,10 @@ impl Definitions {
178180
self.data[index.as_usize()].key.clone()
179181
}
180182

183+
pub fn def_index_for_def_key(&self, key: DefKey) -> Option<DefIndex> {
184+
self.key_map.get(&key).cloned()
185+
}
186+
181187
/// Returns the path from the crate root to `index`. The root
182188
/// nodes are not included in the path (i.e., this will be an
183189
/// empty vector for the crate root). For an inlined item, this
@@ -208,37 +214,6 @@ impl Definitions {
208214
}
209215
}
210216

211-
pub fn retrace_path(&self, path: &DefPath) -> Option<DefIndex> {
212-
debug!("retrace_path(path={:?})", path);
213-
214-
// we assume that we only want to retrace paths relative to
215-
// the crate root
216-
assert!(path.is_local());
217-
218-
let root_key = DefKey {
219-
parent: None,
220-
disambiguated_data: DisambiguatedDefPathData {
221-
data: DefPathData::CrateRoot,
222-
disambiguator: 0,
223-
},
224-
};
225-
let root_id = self.key_map[&root_key];
226-
227-
debug!("retrace_path: root_id={:?}", root_id);
228-
229-
let mut id = root_id;
230-
for data in &path.data {
231-
let key = DefKey { parent: Some(id), disambiguated_data: data.clone() };
232-
debug!("key = {:?}", key);
233-
id = match self.key_map.get(&key) {
234-
Some(&id) => id,
235-
None => return None
236-
};
237-
}
238-
239-
Some(id)
240-
}
241-
242217
pub fn create_def_with_parent(&mut self,
243218
parent: Option<DefIndex>,
244219
node_id: ast::NodeId,

src/librustc/hir/map/mod.rs

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use dep_graph::{DepGraph, DepNode};
1919

2020
use middle::cstore::InlinedItem;
2121
use middle::cstore::InlinedItem as II;
22-
use hir::def_id::{CRATE_DEF_INDEX, DefId};
22+
use hir::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
2323

2424
use syntax::abi::Abi;
2525
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID, };
@@ -285,9 +285,8 @@ impl<'ast> Map<'ast> {
285285
self.definitions.borrow().def_path(def_id.index)
286286
}
287287

288-
pub fn retrace_path(&self, path: &DefPath) -> Option<DefId> {
289-
self.definitions.borrow().retrace_path(path)
290-
.map(DefId::local)
288+
pub fn def_index_for_def_key(&self, def_key: DefKey) -> Option<DefIndex> {
289+
self.definitions.borrow().def_index_for_def_key(def_key)
291290
}
292291

293292
pub fn local_def_id(&self, node: NodeId) -> DefId {

src/librustc/middle/cstore.rs

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -22,12 +22,13 @@
2222
// are *mostly* used as a part of that interface, but these should
2323
// probably get a better home if someone can find one.
2424

25-
use hir::svh::Svh;
26-
use hir::map as hir_map;
2725
use hir::def::{self, Def};
26+
use hir::def_id::{DefId, DefIndex};
27+
use hir::map as hir_map;
28+
use hir::map::definitions::DefKey;
29+
use hir::svh::Svh;
2830
use middle::lang_items;
2931
use ty::{self, Ty, TyCtxt, VariantKind};
30-
use hir::def_id::{DefId, DefIndex};
3132
use mir::repr::Mir;
3233
use mir::mir_map::MirMap;
3334
use session::Session;
@@ -234,6 +235,10 @@ pub trait CrateStore<'tcx> {
234235
fn reachable_ids(&self, cnum: ast::CrateNum) -> Vec<DefId>;
235236

236237
// resolve
238+
fn def_index_for_def_key(&self,
239+
cnum: ast::CrateNum,
240+
def: DefKey)
241+
-> Option<DefIndex>;
237242
fn def_key(&self, def: DefId) -> hir_map::DefKey;
238243
fn relative_def_path(&self, def: DefId) -> hir_map::DefPath;
239244
fn variant_kind(&self, def_id: DefId) -> Option<VariantKind>;
@@ -361,6 +366,12 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
361366
-> Vec<Rc<ty::Method<'tcx>>> { bug!("provided_trait_methods") }
362367
fn trait_item_def_ids(&self, def: DefId)
363368
-> Vec<ty::ImplOrTraitItemId> { bug!("trait_item_def_ids") }
369+
fn def_index_for_def_key(&self,
370+
cnum: ast::CrateNum,
371+
def: DefKey)
372+
-> Option<DefIndex> {
373+
None
374+
}
364375

365376
// impl info
366377
fn impl_items(&self, impl_def_id: DefId) -> Vec<ty::ImplOrTraitItemId>

src/librustc/ty/context.rs

Lines changed: 46 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,14 @@
1111
//! type context book-keeping
1212
1313
use dep_graph::{DepGraph, DepTrackingMap};
14-
use hir::map as ast_map;
1514
use session::Session;
1615
use lint;
1716
use middle;
1817
use middle::cstore::LOCAL_CRATE;
1918
use hir::def::DefMap;
20-
use hir::def_id::DefId;
19+
use hir::def_id::{DefId, DefIndex};
20+
use hir::map as ast_map;
21+
use hir::map::{DefKey, DefPath, DefPathData, DisambiguatedDefPathData};
2122
use middle::free_region::FreeRegionMap;
2223
use middle::region::RegionMaps;
2324
use middle::resolve_lifetime;
@@ -511,6 +512,49 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
511512
}
512513
}
513514

515+
/// Given a def-key `key` and a crate `krate`, finds the def-index
516+
/// that `krate` assigned to `key`. This `DefIndex` will always be
517+
/// relative to `krate`.
518+
///
519+
/// Returns `None` if there is no `DefIndex` with that key.
520+
pub fn def_index_for_def_key(self, krate: ast::CrateNum, key: DefKey)
521+
-> Option<DefIndex> {
522+
if krate == LOCAL_CRATE {
523+
self.map.def_index_for_def_key(key)
524+
} else {
525+
self.sess.cstore.def_index_for_def_key(krate, key)
526+
}
527+
}
528+
529+
pub fn retrace_path(self, path: &DefPath) -> Option<DefId> {
530+
debug!("retrace_path(path={:?})", path);
531+
532+
let root_key = DefKey {
533+
parent: None,
534+
disambiguated_data: DisambiguatedDefPathData {
535+
data: DefPathData::CrateRoot,
536+
disambiguator: 0,
537+
},
538+
};
539+
540+
let root_index = self.def_index_for_def_key(path.krate, root_key)
541+
.expect("no root key?");
542+
543+
debug!("retrace_path: root_index={:?}", root_index);
544+
545+
let mut index = root_index;
546+
for data in &path.data {
547+
let key = DefKey { parent: Some(index), disambiguated_data: data.clone() };
548+
debug!("retrace_path: key={:?}", key);
549+
match self.def_index_for_def_key(path.krate, key) {
550+
Some(i) => index = i,
551+
None => return None,
552+
}
553+
}
554+
555+
Some(DefId { krate: path.krate, index: index })
556+
}
557+
514558
pub fn type_parameter_def(self,
515559
node_id: NodeId)
516560
-> ty::TypeParameterDef<'tcx>

src/librustc_incremental/persist/directory.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ impl DefIdDirectory {
4141

4242
pub fn retrace(&self, tcx: TyCtxt) -> RetracedDefIdDirectory {
4343
let ids = self.paths.iter()
44-
.map(|path| tcx.map.retrace_path(path))
44+
.map(|path| tcx.retrace_path(path))
4545
.collect();
4646
RetracedDefIdDirectory { ids: ids }
4747
}

src/librustc_metadata/creader.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -319,6 +319,7 @@ impl<'a> CrateReader<'a> {
319319
extern_crate: Cell::new(None),
320320
index: decoder::load_index(metadata.as_slice()),
321321
xref_index: decoder::load_xrefs(metadata.as_slice()),
322+
key_map: decoder::load_key_map(metadata.as_slice()),
322323
data: metadata,
323324
cnum_map: RefCell::new(cnum_map),
324325
cnum: cnum,

src/librustc_metadata/csearch.rs

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ use rustc::hir::def_id::{DefId, DefIndex, CRATE_DEF_INDEX};
2222

2323
use rustc::dep_graph::DepNode;
2424
use rustc::hir::map as hir_map;
25+
use rustc::hir::map::DefKey;
2526
use rustc::mir::repr::Mir;
2627
use rustc::mir::mir_map::MirMap;
2728
use rustc::util::nodemap::{FnvHashMap, NodeMap, NodeSet, DefIdMap};
@@ -408,6 +409,14 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
408409
decoder::get_reachable_ids(&cdata)
409410
}
410411

412+
fn def_index_for_def_key(&self,
413+
cnum: ast::CrateNum,
414+
def: DefKey)
415+
-> Option<DefIndex> {
416+
let cdata = self.get_crate_data(cnum);
417+
cdata.key_map.get(&def).cloned()
418+
}
419+
411420
/// Returns the `DefKey` for a given `DefId`. This indicates the
412421
/// parent `DefId` as well as some idea of what kind of data the
413422
/// `DefId` refers to.

src/librustc_metadata/cstore.rs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,8 @@ use index;
2121
use loader;
2222

2323
use rustc::dep_graph::DepGraph;
24-
use rustc::hir::def_id::DefId;
24+
use rustc::hir::def_id::{DefIndex, DefId};
25+
use rustc::hir::map::DefKey;
2526
use rustc::hir::svh::Svh;
2627
use rustc::middle::cstore::{ExternCrate};
2728
use rustc::session::config::PanicStrategy;
@@ -79,6 +80,13 @@ pub struct crate_metadata {
7980
pub index: index::Index,
8081
pub xref_index: index::DenseIndex,
8182

83+
/// For each public item in this crate, we encode a key. When the
84+
/// crate is loaded, we read all the keys and put them in this
85+
/// hashmap, which gives the reverse mapping. This allows us to
86+
/// quickly retrace a `DefPath`, which is needed for incremental
87+
/// compilation support.
88+
pub key_map: FnvHashMap<DefKey, DefIndex>,
89+
8290
/// Flag if this crate is required by an rlib version of this crate, or in
8391
/// other words whether it was explicitly linked to. An example of a crate
8492
/// where this is false is when an allocator crate is injected into the

src/librustc_metadata/decoder.rs

Lines changed: 34 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ use tydecode::TyDecoder;
2525

2626
use rustc::hir::svh::Svh;
2727
use rustc::hir::map as hir_map;
28+
use rustc::hir::map::DefKey;
2829
use rustc::util::nodemap::FnvHashMap;
2930
use rustc::hir;
3031
use rustc::session::config::PanicStrategy;
@@ -95,6 +96,29 @@ pub fn load_xrefs(data: &[u8]) -> index::DenseIndex {
9596
index::DenseIndex::from_buf(index.data, index.start, index.end)
9697
}
9798

99+
// Go through each item in the metadata and create a map from that
100+
// item's def-key to the item's DefIndex.
101+
pub fn load_key_map(data: &[u8]) -> FnvHashMap<DefKey, DefIndex> {
102+
let root_doc = rbml::Doc::new(data);
103+
let items_doc = reader::get_doc(root_doc, tag_items);
104+
let items_data_doc = reader::get_doc(items_doc, tag_items_data);
105+
reader::docs(items_data_doc)
106+
.filter(|&(tag, _)| tag == tag_items_data_item)
107+
.map(|(_, item_doc)| {
108+
// load def-key from item
109+
let key = item_def_key(item_doc);
110+
111+
// load def-index from item; we only encode the full def-id,
112+
// so just pull out the index
113+
let def_id_doc = reader::get_doc(item_doc, tag_def_id);
114+
let def_id = untranslated_def_id(def_id_doc);
115+
assert!(def_id.is_local()); // local to the crate we are decoding, that is
116+
117+
(key, def_id.index)
118+
})
119+
.collect()
120+
}
121+
98122
#[derive(Clone, Copy, Debug, PartialEq)]
99123
enum Family {
100124
ImmStatic, // c
@@ -193,10 +217,14 @@ fn item_symbol(item: rbml::Doc) -> String {
193217
reader::get_doc(item, tag_items_data_item_symbol).as_str().to_string()
194218
}
195219

196-
fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
220+
fn untranslated_def_id(d: rbml::Doc) -> DefId {
197221
let id = reader::doc_as_u64(d);
198222
let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
199-
let def_id = DefId { krate: (id >> 32) as u32, index: index };
223+
DefId { krate: (id >> 32) as u32, index: index }
224+
}
225+
226+
fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
227+
let def_id = untranslated_def_id(d);
200228
translate_def_id(cdata, def_id)
201229
}
202230

@@ -1750,6 +1778,10 @@ pub fn closure_ty<'a, 'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: TyCtxt<'a, 't
17501778
pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey {
17511779
debug!("def_key: id={:?}", id);
17521780
let item_doc = cdata.lookup_item(id);
1781+
item_def_key(item_doc)
1782+
}
1783+
1784+
fn item_def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
17531785
match reader::maybe_get_doc(item_doc, tag_def_key) {
17541786
Some(def_key_doc) => {
17551787
let mut decoder = reader::Decoder::new(def_key_doc);

0 commit comments

Comments
 (0)