From 4c4195f269c731d671650002fc4b0b1edb10d944 Mon Sep 17 00:00:00 2001 From: Michael Woerister Date: Tue, 22 Dec 2015 10:27:20 -0500 Subject: [PATCH] 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". --- src/librustc/front/map/mod.rs | 11 ++++--- src/librustc_metadata/astencode.rs | 15 ++++++---- src/librustc_metadata/decoder.rs | 47 +++++++++++++++++++++++------- 3 files changed, 50 insertions(+), 23 deletions(-) diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs index cbda1e8880b..7de60995445 100644 --- a/src/librustc/front/map/mod.rs +++ b/src/librustc/front/map/mod.rs @@ -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, - def_path: DefPath, + parent_path: Vec, + 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); diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index 714f0a4350b..8f74acd9ebd 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -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, - def_path: ast_map::DefPath, + parent_path: Vec, + parent_def_path: ast_map::DefPath, par_doc: rbml::Doc, orig_did: DefId) -> Result<&'tcx InlinedItem, (Vec, 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, diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 357158c24ba..8126970759e 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -763,29 +763,54 @@ pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Nam pub type DecodeInlinedItem<'a> = Box FnMut(Cmd, &ty::ctxt<'tcx>, - Vec, - hir_map::DefPath, + Vec, // parent_path + hir_map::DefPath, // parent_def_path rbml::Doc, DefId) -> Result<&'tcx InlinedItem, (Vec, 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 } }