]> git.lizzy.rs Git - rust.git/commitdiff
track def-id for inlined items
authorNiko Matsakis <niko@alum.mit.edu>
Wed, 16 Mar 2016 09:31:51 +0000 (05:31 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Fri, 25 Mar 2016 18:07:19 +0000 (14:07 -0400)
src/librustc/front/map/collector.rs
src/librustc/front/map/definitions.rs
src/librustc/front/map/mod.rs
src/librustc_metadata/astencode.rs
src/librustc_metadata/decoder.rs

index 11aea3727299db780397e471a73459aaf8782031..7f66b56b2d3170465e1f3e51d6fe64c580230c65 100644 (file)
@@ -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
     }
index 0f99d85b083fefb76fce0d8d8687592cf5c717d9..bf5fd736526a106e3e1962a65c2a7431ab098938 100644 (file)
@@ -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,
index dfc8560b58de0268dd3fb09ebf3327e117e6b0e7..a1355046f48c1ddea156190ca8b0b493b233b973 100644 (file)
@@ -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);
index 5c5574c3a8300eeab57e5268dd080766a4e40e7b..60f7110764699eeacbae0dfdd10ea8abb1291a5c 100644 (file)
@@ -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()
 }
index 00810ec71abbfa963a1e9113bf0ee9930629bb3b..5c3c7ad1b3023410ac9d01e60b064d36dee2e931 100644 (file)
@@ -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);
             }