Fix def paths creation for items inlined from external crates.

Avoid duplicating the last element of the def path which led to paths like "std::slice::into_vec::into_vec".
This commit is contained in:
Michael Woerister 2015-12-22 10:27:20 -05:00
parent 42c3ef8f9f
commit 4c4195f269
3 changed files with 50 additions and 23 deletions

View File

@ -839,11 +839,10 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
}
/// Used for items loaded from external crate that are being inlined into this
/// crate. The `path` should be the path to the item but should not include
/// the item itself.
/// crate.
pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
path: Vec<PathElem>,
def_path: DefPath,
parent_path: Vec<PathElem>,
parent_def_path: DefPath,
ii: InlinedItem,
fold_ops: F)
-> &'ast InlinedItem {
@ -862,7 +861,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
};
let ii_parent = map.forest.inlined_items.alloc(InlinedParent {
path: path,
path: parent_path,
ii: ii
});
@ -872,7 +871,7 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
map.krate(),
ii_parent,
ii_parent_id,
def_path,
parent_def_path,
mem::replace(&mut *map.map.borrow_mut(), vec![]),
mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new()));
ii_parent.ii.visit(&mut collector);

View File

@ -124,20 +124,20 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
/// ast-map.
pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
tcx: &ty::ctxt<'tcx>,
path: Vec<ast_map::PathElem>,
def_path: ast_map::DefPath,
parent_path: Vec<ast_map::PathElem>,
parent_def_path: ast_map::DefPath,
par_doc: rbml::Doc,
orig_did: DefId)
-> Result<&'tcx InlinedItem, (Vec<ast_map::PathElem>,
ast_map::DefPath)> {
match par_doc.opt_child(c::tag_ast) {
None => Err((path, def_path)),
None => Err((parent_path, parent_def_path)),
Some(ast_doc) => {
let mut path_as_str = None;
debug!("> Decoding inlined fn: {:?}::?",
{
// Do an Option dance to use the path after it is moved below.
let s = ast_map::path_to_string(path.iter().cloned());
let s = ast_map::path_to_string(parent_path.iter().cloned());
path_as_str = Some(s);
path_as_str.as_ref().map(|x| &x[..])
});
@ -152,8 +152,11 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
last_filemap_index: Cell::new(0)
};
let raw_ii = decode_ast(ast_doc);
let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, def_path, raw_ii, dcx);
let ii = ast_map::map_decoded_item(&dcx.tcx.map,
parent_path,
parent_def_path,
raw_ii,
dcx);
let name = match *ii {
InlinedItem::Item(ref i) => i.name,
InlinedItem::Foreign(ref i) => i.name,

View File

@ -763,29 +763,54 @@ pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Nam
pub type DecodeInlinedItem<'a> =
Box<for<'tcx> FnMut(Cmd,
&ty::ctxt<'tcx>,
Vec<hir_map::PathElem>,
hir_map::DefPath,
Vec<hir_map::PathElem>, // parent_path
hir_map::DefPath, // parent_def_path
rbml::Doc,
DefId)
-> Result<&'tcx InlinedItem, (Vec<hir_map::PathElem>,
hir_map::DefPath)> + 'a>;
pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: DefIndex,
pub fn maybe_get_item_ast<'tcx>(cdata: Cmd,
tcx: &ty::ctxt<'tcx>,
id: DefIndex,
mut decode_inlined_item: DecodeInlinedItem)
-> FoundAst<'tcx> {
debug!("Looking up item: {:?}", id);
let item_doc = cdata.lookup_item(id);
let item_did = item_def_id(item_doc, cdata);
let path = item_path(item_doc).split_last().unwrap().1.to_vec();
let def_path = def_path(cdata, id);
match decode_inlined_item(cdata, tcx, path, def_path, item_doc, item_did) {
let parent_path = {
let mut path = item_path(item_doc);
path.pop();
path
};
let parent_def_path = {
let mut def_path = def_path(cdata, id);
def_path.pop();
def_path
};
match decode_inlined_item(cdata,
tcx,
parent_path,
parent_def_path,
item_doc,
item_did) {
Ok(ii) => FoundAst::Found(ii),
Err((path, def_path)) => {
Err((mut parent_path, mut parent_def_path)) => {
match item_parent_item(cdata, item_doc) {
Some(did) => {
let parent_item = cdata.lookup_item(did.index);
match decode_inlined_item(cdata, tcx, path, def_path, parent_item, did) {
Ok(ii) => FoundAst::FoundParent(did, ii),
Some(parent_did) => {
// Remove the last element from the paths, since we are now
// trying to inline the parent.
parent_path.pop();
parent_def_path.pop();
let parent_item = cdata.lookup_item(parent_did.index);
match decode_inlined_item(cdata,
tcx,
parent_path,
parent_def_path,
parent_item,
parent_did) {
Ok(ii) => FoundAst::FoundParent(parent_did, ii),
Err(_) => FoundAst::NotFound
}
}