use rustc_front::hir::*;
use rustc_front::util;
use rustc_front::intravisit::{self, Visitor};
-use middle::def_id::{CRATE_DEF_INDEX, DefIndex};
+use middle::def_id::{CRATE_DEF_INDEX, DefId, DefIndex};
use std::iter::repeat;
use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
use syntax::codemap::Span;
parent: &'ast InlinedParent,
parent_node: NodeId,
parent_def_path: DefPath,
+ parent_def_id: DefId,
map: Vec<MapEntry<'ast>>,
definitions: Definitions)
-> NodeCollector<'ast> {
definitions: definitions,
};
+ assert_eq!(parent_def_path.krate, parent_def_id.krate);
+ let root_path = Box::new(InlinedRootPath {
+ data: parent_def_path.data,
+ def_id: parent_def_id,
+ });
+
collector.insert_entry(parent_node, RootInlinedParent(parent));
- collector.create_def(parent_node, DefPathData::InlinedRoot(parent_def_path));
+ collector.create_def(parent_node, DefPathData::InlinedRoot(root_path));
collector
}
}
pub type DefPath = Vec<DisambiguatedDefPathData>;
+/// Root of an inlined item. We track the `DefPath` of the item within
+/// the original crate but also its def-id. This is kind of an
+/// augmented version of a `DefPath` that includes a `DefId`. This is
+/// all sort of ugly but the hope is that inlined items will be going
+/// away soon anyway.
+///
+/// Some of the constraints that led to the current approach:
+///
+/// - I don't want to have a `DefId` in the main `DefPath` because
+/// that gets serialized for incr. comp., and when reloaded the
+/// `DefId` is no longer valid. I'd rather maintain the invariant
+/// that every `DefId` is valid, and a potentially outdated `DefId` is
+/// represented as a `DefPath`.
+/// - (We don't serialize def-paths from inlined items, so it's ok to have one here.)
+/// - We need to be able to extract the def-id from inline items to
+/// make the symbol name. In theory we could retrace it from the
+/// data, but the metadata doesn't have the required indices, and I
+/// don't want to write the code to create one just for this.
+/// - It may be that we don't actually need `data` at all. We'll have
+/// to see about that.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+pub struct InlinedRootPath {
+ pub data: Vec<DisambiguatedDefPathData>,
+ pub def_id: DefId,
+}
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum DefPathData {
// Root: these should only be used for the root nodes, because
// they are treated specially by the `def_path` function.
CrateRoot,
- InlinedRoot(DefPath),
+ InlinedRoot(Box<InlinedRootPath>),
// Catch-all for random DefId things like DUMMY_NODE_ID
Misc,
pub use self::PathElem::*;
use self::MapEntry::*;
use self::collector::NodeCollector;
-pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData};
+pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData,
+ DisambiguatedDefPathData, InlinedRootPath};
use dep_graph::{DepGraph, DepNode};
id = p,
RootCrate |
- RootInlinedParent(_) => // FIXME(#2369) clarify story about cross-crate dep tracking
+ RootInlinedParent(_) =>
+ // FIXME(#32015) clarify story about cross-crate dep tracking
return DepNode::Krate,
NotPresent =>
pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
parent_path: Vec<PathElem>,
parent_def_path: DefPath,
+ parent_def_id: DefId,
ii: InlinedItem,
fold_ops: F)
-> &'ast InlinedItem {
ii_parent,
ii_parent_id,
parent_def_path,
+ parent_def_id,
mem::replace(&mut *map.map.borrow_mut(), vec![]),
mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()));
ii_parent.ii.visit(&mut collector);
tcx: &TyCtxt<'tcx>,
parent_path: Vec<ast_map::PathElem>,
parent_def_path: ast_map::DefPath,
+ parent_did: DefId,
ast_doc: rbml::Doc,
orig_did: DefId)
-> &'tcx InlinedItem {
let ii = ast_map::map_decoded_item(&dcx.tcx.map,
parent_path,
parent_def_path,
+ parent_did,
decode_ast(ast_doc),
dcx);
let name = match *ii {
}
}
-fn decode_ast(par_doc: rbml::Doc) -> InlinedItem {
- let chi_doc = par_doc.get(c::tag_tree as usize);
+fn decode_ast(item_doc: rbml::Doc) -> InlinedItem {
+ let chi_doc = item_doc.get(c::tag_tree as usize);
let mut rbml_r = reader::Decoder::new(chi_doc);
rbml_r.read_opaque(|decoder, _| Decodable::decode(decoder)).unwrap()
}
}
#[cfg(test)]
-fn decode_item_ast(par_doc: rbml::Doc) -> hir::Item {
- let chi_doc = par_doc.get(c::tag_tree as usize);
+fn decode_item_ast(item_doc: rbml::Doc) -> hir::Item {
+ let chi_doc = item_doc.get(c::tag_tree as usize);
let mut d = reader::Decoder::new(chi_doc);
Decodable::decode(&mut d).unwrap()
}
debug!("Looking up item: {:?}", id);
let item_doc = cdata.lookup_item(id);
let item_did = item_def_id(item_doc, cdata);
+ let parent_def_id = DefId {
+ krate: cdata.cnum,
+ index: def_key(cdata, id).parent.unwrap()
+ };
let mut parent_path = item_path(item_doc);
parent_path.pop();
let mut parent_def_path = def_path(cdata, id);
parent_def_path.pop();
if let Some(ast_doc) = reader::maybe_get_doc(item_doc, tag_ast as usize) {
- let ii = decode_inlined_item(cdata, tcx, parent_path,
+ let ii = decode_inlined_item(cdata,
+ tcx,
+ parent_path,
parent_def_path,
- ast_doc, item_did);
+ parent_def_id,
+ ast_doc,
+ item_did);
return FoundAst::Found(ii);
} else if let Some(parent_did) = item_parent_item(cdata, item_doc) {
// Remove the last element from the paths, since we are now
// trying to inline the parent.
- parent_path.pop();
- parent_def_path.pop();
+ let grandparent_def_id = DefId {
+ krate: cdata.cnum,
+ index: def_key(cdata, parent_def_id.index).parent.unwrap()
+ };
+ let mut grandparent_path = parent_path;
+ grandparent_path.pop();
+ let mut grandparent_def_path = parent_def_path;
+ grandparent_def_path.pop();
let parent_doc = cdata.lookup_item(parent_did.index);
if let Some(ast_doc) = reader::maybe_get_doc(parent_doc, tag_ast as usize) {
- let ii = decode_inlined_item(cdata, tcx, parent_path,
- parent_def_path,
- ast_doc, parent_did);
+ let ii = decode_inlined_item(cdata,
+ tcx,
+ grandparent_path,
+ grandparent_def_path,
+ grandparent_def_id,
+ ast_doc,
+ parent_did);
if let &InlinedItem::Item(ref i) = ii {
return FoundAst::FoundParent(parent_did, i);
}