track def-id for inlined items
This commit is contained in:
parent
2475707322
commit
65c0b7c292
@ -14,7 +14,7 @@
|
||||
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;
|
||||
@ -50,6 +50,7 @@ pub fn extend(krate: &'ast Crate,
|
||||
parent: &'ast InlinedParent,
|
||||
parent_node: NodeId,
|
||||
parent_def_path: DefPath,
|
||||
parent_def_id: DefId,
|
||||
map: Vec<MapEntry<'ast>>,
|
||||
definitions: Definitions)
|
||||
-> NodeCollector<'ast> {
|
||||
@ -60,8 +61,14 @@ pub fn extend(krate: &'ast Crate,
|
||||
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
|
||||
}
|
||||
|
@ -60,13 +60,38 @@ pub struct DefData {
|
||||
}
|
||||
|
||||
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,
|
||||
|
@ -12,7 +12,8 @@
|
||||
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};
|
||||
|
||||
@ -322,7 +323,8 @@ fn dep_node(&self, id0: NodeId) -> 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 =>
|
||||
@ -958,6 +960,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
|
||||
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 {
|
||||
@ -987,6 +990,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
|
||||
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);
|
||||
|
@ -125,6 +125,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
|
||||
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 {
|
||||
@ -149,6 +150,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
|
||||
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 {
|
||||
@ -349,8 +351,8 @@ fn simplify_ast(ii: InlinedItemRef) -> InlinedItem {
|
||||
}
|
||||
}
|
||||
|
||||
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()
|
||||
}
|
||||
@ -1280,8 +1282,8 @@ fn encode_item_ast(rbml_w: &mut Encoder, item: &hir::Item) {
|
||||
}
|
||||
|
||||
#[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()
|
||||
}
|
||||
|
@ -803,25 +803,43 @@ pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &TyCtxt<'tcx>, id: DefIndex)
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user