]> git.lizzy.rs Git - rust.git/commitdiff
Convert DefId to use DefIndex, which is an index into a list of
authorNiko Matsakis <niko@alum.mit.edu>
Thu, 17 Sep 2015 18:29:59 +0000 (14:29 -0400)
committerNiko Matsakis <niko@alum.mit.edu>
Thu, 1 Oct 2015 14:43:07 +0000 (10:43 -0400)
paths, and construct paths for all definitions. Also, stop rewriting
DefIds for closures, and instead just load the closure data from
the original def-id, which may be in another crate.

40 files changed:
src/librustc/front/map/collector.rs
src/librustc/front/map/definitions.rs [new file with mode: 0644]
src/librustc/front/map/mod.rs
src/librustc/metadata/common.rs
src/librustc/metadata/creader.rs
src/librustc/metadata/csearch.rs
src/librustc/metadata/cstore.rs
src/librustc/metadata/decoder.rs
src/librustc/metadata/encoder.rs
src/librustc/metadata/index.rs
src/librustc/metadata/tydecode.rs
src/librustc/middle/astencode.rs
src/librustc/middle/const_eval.rs
src/librustc/middle/def_id.rs
src/librustc/middle/expr_use_visitor.rs
src/librustc/middle/infer/mod.rs
src/librustc/middle/lang_items.rs
src/librustc/middle/stability.rs
src/librustc/middle/traits/select.rs
src/librustc/middle/ty/context.rs
src/librustc/middle/ty/mod.rs
src/librustc/middle/ty/util.rs
src/librustc/util/ppaux.rs
src/librustc_lint/builtin.rs
src/librustc_resolve/build_reduced_graph.rs
src/librustc_trans/back/link.rs
src/librustc_trans/save/recorder.rs
src/librustc_trans/trans/base.rs
src/librustc_trans/trans/closure.rs
src/librustc_trans/trans/common.rs
src/librustc_trans/trans/consts.rs
src/librustc_trans/trans/debuginfo/metadata.rs
src/librustc_trans/trans/expr.rs
src/librustc_trans/trans/foreign.rs
src/librustc_trans/trans/inline.rs
src/librustc_trans/trans/monomorphize.rs
src/librustdoc/clean/mod.rs
src/librustdoc/html/format.rs
src/librustdoc/html/render.rs
src/libsyntax/ast.rs

index a252992812ebb1520a35bdcb968eaa3b02543adf..5f3148c7c33c57571882e009d36932884f324fa7 100644 (file)
 use rustc_front::hir::*;
 use rustc_front::util;
 use rustc_front::visit::{self, Visitor};
+use middle::def_id::{CRATE_DEF_INDEX, DefIndex};
 use std::iter::repeat;
 use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
 use syntax::codemap::Span;
-use util::nodemap::NodeSet;
 
 /// A Visitor that walks over an AST and collects Node's into an AST
 /// Map.
 pub struct NodeCollector<'ast> {
     pub map: Vec<MapEntry<'ast>>,
-    pub definitions_map: NodeSet,
+    pub definitions: Definitions,
     pub parent_node: NodeId,
 }
 
@@ -31,35 +31,59 @@ impl<'ast> NodeCollector<'ast> {
     pub fn root() -> NodeCollector<'ast> {
         let mut collector = NodeCollector {
             map: vec![],
-            definitions_map: NodeSet(),
+            definitions: Definitions::new(),
             parent_node: CRATE_NODE_ID,
         };
         collector.insert_entry(CRATE_NODE_ID, RootCrate);
-        collector.create_def(CRATE_NODE_ID);
-        collector.create_def(DUMMY_NODE_ID);
+
+        let result = collector.create_def_with_parent(None, CRATE_NODE_ID, DefPathData::CrateRoot);
+        assert_eq!(result, CRATE_DEF_INDEX);
+
+        collector.create_def_with_parent(Some(CRATE_DEF_INDEX), DUMMY_NODE_ID, DefPathData::Misc);
+
         collector
     }
 
     pub fn extend(parent: &'ast InlinedParent,
                   parent_node: NodeId,
+                  parent_def_path: DefPath,
                   map: Vec<MapEntry<'ast>>,
-                  definitions_map: NodeSet)
+                  definitions: Definitions)
                   -> NodeCollector<'ast> {
         let mut collector = NodeCollector {
             map: map,
-            definitions_map: definitions_map,
-            parent_node: parent_node
+            parent_node: parent_node,
+            definitions: definitions,
         };
+
         collector.insert_entry(parent_node, RootInlinedParent(parent));
+        collector.create_def(parent_node, DefPathData::InlinedRoot(parent_def_path));
 
         collector
     }
 
-    fn create_def(&mut self, node: NodeId) {
-        let is_new = self.definitions_map.insert(node);
-        assert!(is_new,
-                "two entries for node id `{}` -- previous is `{:?}`",
-                node, node);
+    fn parent_def(&self) -> Option<DefIndex> {
+        let mut parent_node = Some(self.parent_node);
+        while let Some(p) = parent_node {
+            if let Some(q) = self.definitions.opt_def_index(p) {
+                return Some(q);
+            }
+            parent_node = self.map[p as usize].parent_node();
+        }
+        None
+    }
+
+    fn create_def(&mut self, node_id: NodeId, data: DefPathData) -> DefIndex {
+        let parent_def = self.parent_def();
+        self.definitions.create_def_with_parent(parent_def, node_id, data)
+    }
+
+    fn create_def_with_parent(&mut self,
+                              parent: Option<DefIndex>,
+                              node_id: NodeId,
+                              data: DefPathData)
+                              -> DefIndex {
+        self.definitions.create_def_with_parent(parent, node_id, data)
     }
 
     fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
@@ -71,6 +95,11 @@ fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
         self.map[id as usize] = entry;
     }
 
+    fn insert_def(&mut self, id: NodeId, node: Node<'ast>, data: DefPathData) -> DefIndex {
+        self.insert(id, node);
+        self.create_def(id, data)
+    }
+
     fn insert(&mut self, id: NodeId, node: Node<'ast>) {
         let entry = MapEntry::from_node(self.parent_node, node);
         self.insert_entry(id, entry);
@@ -85,47 +114,61 @@ fn visit_fn_decl(&mut self, decl: &'ast FnDecl) {
 
 impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
     fn visit_item(&mut self, i: &'ast Item) {
-        self.insert(i.id, NodeItem(i));
+        // Pick the def data. This need not be unique, but the more
+        // information we encapsulate into
+        let def_data = match i.node {
+            ItemDefaultImpl(..) | ItemImpl(..) => DefPathData::Impl,
+            ItemEnum(..) | ItemStruct(..) | ItemTrait(..) => DefPathData::Type(i.name),
+            ItemExternCrate(..) | ItemMod(..) => DefPathData::Mod(i.name),
+            ItemStatic(..) | ItemConst(..) | ItemFn(..) => DefPathData::Value(i.name),
+            _ => DefPathData::Misc,
+        };
+
+        self.insert_def(i.id, NodeItem(i), def_data);
 
         let parent_node = self.parent_node;
         self.parent_node = i.id;
 
-        self.create_def(i.id);
-
         match i.node {
-            ItemImpl(..) => { }
+            ItemImpl(..) => {}
             ItemEnum(ref enum_definition, _) => {
                 for v in &enum_definition.variants {
-                    self.insert(v.node.id, NodeVariant(&**v));
-                    self.create_def(v.node.id);
+                    let variant_def_index =
+                        self.insert_def(v.node.id,
+                                        NodeVariant(&**v),
+                                        DefPathData::EnumVariant(v.node.name));
 
                     match v.node.kind {
                         TupleVariantKind(ref args) => {
                             for arg in args {
-                                self.create_def(arg.id);
+                                self.create_def_with_parent(Some(variant_def_index),
+                                                            arg.id,
+                                                            DefPathData::PositionalField);
                             }
                         }
                         StructVariantKind(ref def) => {
                             for field in &def.fields {
-                                self.create_def(field.node.id);
+                                self.create_def_with_parent(
+                                    Some(variant_def_index),
+                                    field.node.id,
+                                    DefPathData::Field(field.node.kind));
                             }
                         }
                     }
                 }
             }
-            ItemForeignMod(..) => {}
+            ItemForeignMod(..) => {
+            }
             ItemStruct(ref struct_def, _) => {
                 // If this is a tuple-like struct, register the constructor.
-                match struct_def.ctor_id {
-                    Some(ctor_id) => {
-                        self.insert(ctor_id, NodeStructCtor(&**struct_def));
-                        self.create_def(ctor_id);
-                    }
-                    None => {}
+                if let Some(ctor_id) = struct_def.ctor_id {
+                    self.insert_def(ctor_id,
+                                    NodeStructCtor(&**struct_def),
+                                    DefPathData::StructCtor);
                 }
 
                 for field in &struct_def.fields {
-                    self.create_def(field.node.id);
+                    self.create_def(field.node.id, DefPathData::Field(field.node.kind));
                 }
             }
             ItemTrait(_, _, ref bounds, _) => {
@@ -152,8 +195,9 @@ fn visit_item(&mut self, i: &'ast Item) {
     }
 
     fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
-        self.insert(foreign_item.id, NodeForeignItem(foreign_item));
-        self.create_def(foreign_item.id);
+        self.insert_def(foreign_item.id,
+                        NodeForeignItem(foreign_item),
+                        DefPathData::Value(foreign_item.name));
 
         let parent_node = self.parent_node;
         self.parent_node = foreign_item.id;
@@ -163,58 +207,71 @@ fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
 
     fn visit_generics(&mut self, generics: &'ast Generics) {
         for ty_param in generics.ty_params.iter() {
-            self.create_def(ty_param.id);
-            self.insert(ty_param.id, NodeTyParam(ty_param));
+            self.insert_def(ty_param.id,
+                            NodeTyParam(ty_param),
+                            DefPathData::TypeParam(ty_param.name));
         }
 
         visit::walk_generics(self, generics);
     }
 
     fn visit_trait_item(&mut self, ti: &'ast TraitItem) {
+        let def_data = match ti.node {
+            MethodTraitItem(..) | ConstTraitItem(..) => DefPathData::Value(ti.name),
+            TypeTraitItem(..) => DefPathData::Type(ti.name),
+        };
+
         self.insert(ti.id, NodeTraitItem(ti));
-        self.create_def(ti.id);
+        self.create_def(ti.id, def_data);
+
+        let parent_node = self.parent_node;
+        self.parent_node = ti.id;
 
         match ti.node {
             ConstTraitItem(_, Some(ref expr)) => {
-                self.create_def(expr.id);
+                self.create_def(expr.id, DefPathData::Initializer);
             }
             _ => { }
         }
 
-        let parent_node = self.parent_node;
-        self.parent_node = ti.id;
         visit::walk_trait_item(self, ti);
+
         self.parent_node = parent_node;
     }
 
     fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
-        self.insert(ii.id, NodeImplItem(ii));
-        self.create_def(ii.id);
+        let def_data = match ii.node {
+            MethodImplItem(..) | ConstImplItem(..) => DefPathData::Value(ii.name),
+            TypeImplItem(..) => DefPathData::Type(ii.name),
+        };
+
+        self.insert_def(ii.id, NodeImplItem(ii), def_data);
+
+        let parent_node = self.parent_node;
+        self.parent_node = ii.id;
 
         match ii.node {
             ConstImplItem(_, ref expr) => {
-                self.create_def(expr.id);
+                self.create_def(expr.id, DefPathData::Initializer);
             }
             _ => { }
         }
 
-        let parent_node = self.parent_node;
-        self.parent_node = ii.id;
         visit::walk_impl_item(self, ii);
+
         self.parent_node = parent_node;
     }
 
     fn visit_pat(&mut self, pat: &'ast Pat) {
         let maybe_binding = match pat.node {
-            PatIdent(..) => true,
-            _ => false
+            PatIdent(_, id, _) => Some(id.node),
+            _ => None
         };
 
-        self.insert(pat.id,
-                    if maybe_binding {NodeLocal(pat)} else {NodePat(pat)});
-
-        if maybe_binding {
-            self.create_def(pat.id);
+        if let Some(id) = maybe_binding {
+            self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name));
+        } else {
+            self.insert(pat.id, NodePat(pat));
         }
 
         let parent_node = self.parent_node;
@@ -227,8 +284,8 @@ fn visit_expr(&mut self, expr: &'ast Expr) {
         self.insert(expr.id, NodeExpr(expr));
 
         match expr.node {
-            ExprClosure(..) => self.create_def(expr.id),
-            _ => (),
+            ExprClosure(..) => { self.create_def(expr.id, DefPathData::ClosureExpr); }
+            _ => { }
         }
 
         let parent_node = self.parent_node;
@@ -276,12 +333,12 @@ fn visit_lifetime(&mut self, lifetime: &'ast Lifetime) {
     }
 
     fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) {
-        self.create_def(def.lifetime.id);
+        self.create_def(def.lifetime.id, DefPathData::LifetimeDef(def.lifetime.name));
         self.visit_lifetime(&def.lifetime);
     }
 
     fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) {
-        self.create_def(macro_def.id);
+        self.create_def(macro_def.id, DefPathData::MacroDef(macro_def.name));
     }
 }
 
diff --git a/src/librustc/front/map/definitions.rs b/src/librustc/front/map/definitions.rs
new file mode 100644 (file)
index 0000000..c1eb5f1
--- /dev/null
@@ -0,0 +1,263 @@
+// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
+// file at the top-level directory of this distribution and at
+// http://rust-lang.org/COPYRIGHT.
+//
+// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
+// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
+// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
+// option. This file may not be copied, modified, or distributed
+// except according to those terms.
+
+use metadata::cstore::LOCAL_CRATE;
+use middle::def_id::{DefId, DefIndex};
+use rustc_data_structures::fnv::FnvHashMap;
+use rustc_front::hir;
+use syntax::ast;
+use syntax::parse::token::InternedString;
+use util::nodemap::NodeMap;
+
+#[derive(Clone)]
+pub struct Definitions {
+    data: Vec<DefData>,
+    key_map: FnvHashMap<DefKey, DefIndex>,
+    node_map: NodeMap<DefIndex>,
+}
+
+/// A unique identifier that we can use to lookup a definition
+/// precisely. It combines the index of the definition's parent (if
+/// any) with a `DisambiguatedDefPathData`.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+pub struct DefKey {
+    /// Parent path.
+    pub parent: Option<DefIndex>,
+
+    /// Identifier of this node.
+    pub disambiguated_data: DisambiguatedDefPathData,
+}
+
+/// Pair of `DefPathData` and an integer disambiguator. The integer is
+/// normally 0, but in the event that there are multiple defs with the
+/// same `parent` and `data`, we use this field to disambiguate
+/// between them. This introduces some artificial ordering dependency
+/// but means that if you have (e.g.) two impls for the same type in
+/// the same module, they do get distinct def-ids.
+#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
+pub struct DisambiguatedDefPathData {
+    pub data: DefPathData,
+    pub disambiguator: u32
+}
+
+/// For each definition, we track the following data.  A definition
+/// here is defined somewhat circularly as "something with a def-id",
+/// but it generally corresponds to things like structs, enums, etc.
+/// There are also some rather random cases (like const initializer
+/// expressions) that are mostly just leftovers.
+#[derive(Clone, Debug)]
+pub struct DefData {
+    pub key: DefKey,
+
+    /// Local ID within the HIR.
+    pub node_id: ast::NodeId,
+}
+
+pub type DefPath = Vec<DisambiguatedDefPathData>;
+
+#[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),
+
+    // Catch-all for random DefId things like DUMMY_NODE_ID
+    Misc,
+
+    // Different kinds of items and item-like things:
+    Impl,
+    Type(ast::Name),
+    Mod(ast::Name),
+    Value(ast::Name),
+    MacroDef(ast::Name),
+    ClosureExpr,
+
+    // Subportions of items
+    TypeParam(ast::Name),
+    LifetimeDef(ast::Name),
+    EnumVariant(ast::Name),
+    PositionalField,
+    Field(hir::StructFieldKind),
+    StructCtor, // implicit ctor for a tuple-like struct
+    Initializer, // initializer for a const
+    Binding(ast::Name), // pattern binding
+
+    // An external crate that does not have an `extern crate` in this
+    // crate.
+    DetachedCrate(ast::Name),
+}
+
+impl Definitions {
+    pub fn new() -> Definitions {
+        Definitions {
+            data: vec![],
+            key_map: FnvHashMap(),
+            node_map: NodeMap(),
+        }
+    }
+
+    pub fn len(&self) -> usize {
+        self.data.len()
+    }
+
+    pub fn def_key(&self, index: DefIndex) -> DefKey {
+        self.data[index.as_usize()].key.clone()
+    }
+
+    /// Returns the path from the crate root to `index`. The root
+    /// nodes are not included in the path (i.e., this will be an
+    /// empty vector for the crate root). For an inlined item, this
+    /// will be the path of the item in the external crate (but the
+    /// path will begin with the path to the external crate).
+    pub fn def_path(&self, index: DefIndex) -> DefPath {
+        make_def_path(index, |p| self.def_key(p))
+    }
+
+    pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
+        self.node_map.get(&node).cloned()
+    }
+
+    pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<DefId> {
+        self.opt_def_index(node).map(DefId::local)
+    }
+
+    pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
+        if def_id.krate == LOCAL_CRATE {
+            assert!(def_id.index.as_usize() < self.data.len());
+            Some(self.data[def_id.index.as_usize()].node_id)
+        } else {
+            None
+        }
+    }
+
+    pub fn create_def_with_parent(&mut self,
+                                  parent: Option<DefIndex>,
+                                  node_id: ast::NodeId,
+                                  data: DefPathData)
+                                  -> DefIndex {
+        assert!(!self.node_map.contains_key(&node_id),
+                "adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
+                node_id,
+                data,
+                self.data[self.node_map[&node_id].as_usize()]);
+
+        // Find a unique DefKey. This basically means incrementing the disambiguator
+        // until we get no match.
+        let mut key = DefKey {
+            parent: parent,
+            disambiguated_data: DisambiguatedDefPathData {
+                data: data,
+                disambiguator: 0
+            }
+        };
+
+        while self.key_map.contains_key(&key) {
+            key.disambiguated_data.disambiguator += 1;
+        }
+
+        // Create the definition.
+        let index = DefIndex::new(self.data.len());
+        self.data.push(DefData { key: key.clone(), node_id: node_id });
+        self.node_map.insert(node_id, index);
+        self.key_map.insert(key, index);
+
+        index
+    }
+}
+
+impl DefPathData {
+    pub fn as_interned_str(&self) -> InternedString {
+        use self::DefPathData::*;
+        match *self {
+            Type(name) |
+            Mod(name) |
+            Value(name) |
+            MacroDef(name) |
+            TypeParam(name) |
+            LifetimeDef(name) |
+            EnumVariant(name) |
+            DetachedCrate(name) |
+            Binding(name) => {
+                name.as_str()
+            }
+
+            Field(hir::StructFieldKind::NamedField(name, _)) => {
+                name.as_str()
+            }
+
+            PositionalField |
+            Field(hir::StructFieldKind::UnnamedField(_)) => {
+                InternedString::new("<field>")
+            }
+
+            // note that this does not show up in user printouts
+            CrateRoot => {
+                InternedString::new("<root>")
+            }
+
+            // note that this does not show up in user printouts
+            InlinedRoot(_) => {
+                InternedString::new("<inlined-root>")
+            }
+
+            Misc => {
+                InternedString::new("?")
+            }
+
+            Impl => {
+                InternedString::new("<impl>")
+            }
+
+            ClosureExpr => {
+                InternedString::new("<closure>")
+            }
+
+            StructCtor => {
+                InternedString::new("<constructor>")
+            }
+
+            Initializer => {
+                InternedString::new("<initializer>")
+            }
+        }
+    }
+
+    pub fn to_string(&self) -> String {
+        self.as_interned_str().to_string()
+    }
+}
+
+pub fn make_def_path<FN>(start_index: DefIndex, mut get_key: FN) -> DefPath
+    where FN: FnMut(DefIndex) -> DefKey
+{
+    let mut result = vec![];
+    let mut index = Some(start_index);
+    while let Some(p) = index {
+        let key = get_key(p);
+        match key.disambiguated_data.data {
+            DefPathData::CrateRoot => {
+                assert!(key.parent.is_none());
+                break;
+            }
+            DefPathData::InlinedRoot(ref p) => {
+                assert!(key.parent.is_none());
+                result.extend(p.iter().cloned().rev());
+                break;
+            }
+            _ => {
+                result.push(key.disambiguated_data);
+                index = key.parent;
+            }
+        }
+    }
+    result.reverse();
+    result
+}
index 0486fd3a0d1bb1cf9d2c79ff6ec7cb9132444e2f..aba6429abaefd08d7f54a04bff0c16abac340490 100644 (file)
 pub use self::PathElem::*;
 use self::MapEntry::*;
 use self::collector::NodeCollector;
+pub use self::definitions::{Definitions, DefKey, DefPath, DefPathData, DisambiguatedDefPathData};
 
-use metadata::cstore::LOCAL_CRATE;
 use metadata::inline::InlinedItem;
 use metadata::inline::InlinedItem as II;
 use middle::def_id::DefId;
-use util::nodemap::NodeSet;
 
 use syntax::abi;
 use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID};
@@ -39,6 +38,7 @@
 
 pub mod blocks;
 mod collector;
+pub mod definitions;
 
 #[derive(Clone, Copy, PartialEq, Debug)]
 pub enum PathElem {
@@ -268,10 +268,28 @@ pub struct Map<'ast> {
     /// plain old integers.
     map: RefCell<Vec<MapEntry<'ast>>>,
 
-    definitions_map: RefCell<NodeSet>,
+    definitions: RefCell<Definitions>,
 }
 
 impl<'ast> Map<'ast> {
+    pub fn num_local_def_ids(&self) -> usize {
+        self.definitions.borrow().len()
+    }
+
+    pub fn def_key(&self, def_id: DefId) -> DefKey {
+        assert!(def_id.is_local());
+        self.definitions.borrow().def_key(def_id.index)
+    }
+
+    pub fn def_path_from_id(&self, id: NodeId) -> DefPath {
+        self.def_path(self.local_def_id(id))
+    }
+
+    pub fn def_path(&self, def_id: DefId) -> DefPath {
+        assert!(def_id.is_local());
+        self.definitions.borrow().def_path(def_id.index)
+    }
+
     pub fn local_def_id(&self, node: NodeId) -> DefId {
         self.opt_local_def_id(node).unwrap_or_else(|| {
             panic!("local_def_id: no entry for `{}`, which has a map of `{:?}`",
@@ -280,30 +298,27 @@ pub fn local_def_id(&self, node: NodeId) -> DefId {
     }
 
     pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
-        if self.definitions_map.borrow().contains(&node) {
-            Some(DefId::xxx_local(node))
-        } else {
-            None
-        }
+        self.definitions.borrow().opt_local_def_id(node)
     }
 
     pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
-        if def_id.krate == LOCAL_CRATE {
-            assert!(self.definitions_map.borrow().contains(&def_id.xxx_node));
-            Some(def_id.xxx_node)
-        } else {
-            None
-        }
+        self.definitions.borrow().as_local_node_id(def_id)
     }
 
     /// for default methods, we create a fake node-id; this method
     /// adds that fake node-id to the def-id tables
     pub fn synthesize_default_method_def_id(&self,
-                                            _impl_def_id: DefId,
-                                            new_method_id: NodeId)
+                                            impl_def_id: DefId,
+                                            new_method_id: NodeId,
+                                            method_name: Name)
                                             -> DefId {
-        self.definitions_map.borrow_mut().insert(new_method_id);
-        DefId::xxx_local(new_method_id)
+        assert!(impl_def_id.is_local());
+        let index =
+            self.definitions.borrow_mut()
+                            .create_def_with_parent(Some(impl_def_id.index),
+                                                    new_method_id,
+                                                    DefPathData::Value(method_name));
+        DefId::local(index)
     }
 
     fn entry_count(&self) -> usize {
@@ -791,7 +806,7 @@ fn new_span(&mut self, span: Span) -> Span {
 pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
     let mut collector = NodeCollector::root();
     visit::walk_crate(&mut collector, &forest.krate);
-    let NodeCollector { map, definitions_map, .. } = collector;
+    let NodeCollector { map, definitions, .. } = collector;
 
     if log_enabled!(::log::DEBUG) {
         // This only makes sense for ordered stores; note the
@@ -812,7 +827,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
     Map {
         forest: forest,
         map: RefCell::new(map),
-        definitions_map: RefCell::new(definitions_map),
+        definitions: RefCell::new(definitions),
     }
 }
 
@@ -821,6 +836,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
 /// the item itself.
 pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
                                           path: Vec<PathElem>,
+                                          def_path: DefPath,
                                           ii: InlinedItem,
                                           fold_ops: F)
                                           -> &'ast InlinedItem {
@@ -845,14 +861,16 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
 
     let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
     let mut collector =
-        NodeCollector::extend(ii_parent,
-                              ii_parent_id,
-                              mem::replace(&mut *map.map.borrow_mut(), vec![]),
-                              mem::replace(&mut *map.definitions_map.borrow_mut(), NodeSet()));
+        NodeCollector::extend(
+            ii_parent,
+            ii_parent_id,
+            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);
 
     *map.map.borrow_mut() = collector.map;
-    *map.definitions_map.borrow_mut() = collector.definitions_map;
+    *map.definitions.borrow_mut() = collector.definitions;
 
     &ii_parent.ii
 }
index a6cbb4ec50490467bed45a7a6fac0d6582477826..7b8ad78da74dc1b319f6910c0907fcc4f91fc0e2 100644 (file)
 
 pub const tag_items_data_item_is_tuple_struct_ctor: usize = 0x29;
 
-pub const tag_index: usize = 0x2a;
+pub const tag_items_closure_kind: usize = 0x2a;
 
-// GAP 0x2b, 0x2c, 0x2d, 0x2e
+pub const tag_items_closure_ty: usize = 0x2b;
+
+pub const tag_index: usize = 0x2c;
+
+pub const tag_def_key: usize = 0x2d;
+
+// GAP 0x2e
 
 pub const tag_meta_item_name_value: usize = 0x2f;
 
@@ -137,8 +143,7 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
         tag_table_adjustments = 0x61,
         tag_table_moves_map = 0x62,
         tag_table_capture_map = 0x63,
-        tag_table_closure_tys = 0x64,
-        tag_table_closure_kinds = 0x65,
+            // GAP 0x64, 0x65
         tag_table_upvar_capture_map = 0x66,
         tag_table_capture_modes = 0x67,
         // GAP 0x68
@@ -162,12 +167,12 @@ pub enum astencode_tag { // Reserves 0x50 -- 0x6f
 // tag_lang_items
 // - tag_lang_items_item
 //   - tag_lang_items_item_id: u32
-//   - tag_lang_items_item_node_id: u32
+//   - tag_lang_items_item_index: u32
 
 pub const tag_lang_items: usize = 0x107; // top-level only
 pub const tag_lang_items_item: usize = 0x73;
 pub const tag_lang_items_item_id: usize = 0x74;
-pub const tag_lang_items_item_node_id: usize = 0x75;
+pub const tag_lang_items_item_index: usize = 0x75;
 pub const tag_lang_items_missing: usize = 0x76;
 
 pub const tag_item_unnamed_field: usize = 0x77;
@@ -215,7 +220,7 @@ pub struct LinkMeta {
 
 pub const tag_struct_fields: usize = 0x10d; // top-level only
 pub const tag_struct_field: usize = 0x8a;
-pub const tag_struct_field_id: usize = 0x8b;
+// GAP 0x8b
 
 pub const tag_attribute_is_sugared_doc: usize = 0x8c;
 
index 04f164c296d2e984bda7f52e71ba77d9fa205fd0..fe4a909a08516ddbae4d87d3f894cd0d03157ce2 100644 (file)
@@ -325,6 +325,7 @@ fn register_crate(&mut self,
         let cmeta = Rc::new(cstore::crate_metadata {
             name: name.to_string(),
             local_path: RefCell::new(SmallVector::zero()),
+            local_def_path: RefCell::new(vec![]),
             index: decoder::load_index(metadata.as_slice()),
             data: metadata,
             cnum_map: RefCell::new(cnum_map),
@@ -548,7 +549,8 @@ pub fn find_plugin_registrar(&mut self, span: Span, name: &str)
             self.sess.abort_if_errors();
         }
 
-        let registrar = decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
+        let registrar =
+            decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice())
             .map(|id| decoder::get_symbol_from_buf(ekrate.metadata.as_slice(), id));
 
         match (ekrate.dylib.as_ref(), registrar) {
@@ -751,6 +753,9 @@ fn process_item(&mut self, i: &hir::Item) {
                                                               i.span,
                                                               PathKind::Crate,
                                                               true);
+                        let def_id = self.ast_map.local_def_id(i.id);
+                        let def_path = self.ast_map.def_path(def_id);
+                        cmeta.update_local_def_path(def_path);
                         self.ast_map.with_path(i.id, |path| {
                             cmeta.update_local_path(path)
                         });
index 70a969e4d8221142fe79f35a9505c7fd2dac32e0..402aa52612e875f993f585c064dd52e6301c664b 100644 (file)
@@ -14,7 +14,7 @@
 use metadata::cstore;
 use metadata::decoder;
 use metadata::inline::InlinedItem;
-use middle::def_id::DefId;
+use middle::def_id::{DefId, DefIndex};
 use middle::lang_items;
 use middle::ty;
 use util::nodemap::FnvHashMap;
@@ -33,7 +33,7 @@ pub struct MethodInfo {
 
 pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_symbol(&cdata, def.xxx_node)
+    decoder::get_symbol(&cdata, def.index)
 }
 
 /// Iterates over all the language items in the given crate.
@@ -41,7 +41,7 @@ pub fn each_lang_item<F>(cstore: &cstore::CStore,
                          cnum: ast::CrateNum,
                          f: F)
                          -> bool where
-    F: FnMut(ast::NodeId, usize) -> bool,
+    F: FnMut(DefIndex, usize) -> bool,
 {
     let crate_data = cstore.get_crate_data(cnum);
     decoder::each_lang_item(&*crate_data, f)
@@ -59,7 +59,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore,
     };
     decoder::each_child_of_item(cstore.intr.clone(),
                                 &*crate_data,
-                                def_id.xxx_node,
+                                def_id.index,
                                 get_crate_data,
                                 callback)
 }
@@ -83,7 +83,7 @@ pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
 pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    let path = decoder::get_item_path(&*cdata, def.xxx_node);
+    let path = decoder::get_item_path(&*cdata, def.index);
 
     cdata.with_local_path(|cpath| {
         let mut r = Vec::with_capacity(cpath.len() + path.len());
@@ -96,7 +96,7 @@ pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> {
 pub fn get_item_name(tcx: &ty::ctxt, def: DefId) -> ast::Name {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_item_name(&cstore.intr, &cdata, def.xxx_node)
+    decoder::get_item_name(&cstore.intr, &cdata, def.index)
 }
 
 pub enum FoundAst<'ast> {
@@ -113,14 +113,14 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId,
                                 -> FoundAst<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::maybe_get_item_ast(&*cdata, tcx, def.xxx_node, decode_inlined_item)
+    decoder::maybe_get_item_ast(&*cdata, tcx, def.index, decode_inlined_item)
 }
 
 /// Returns information about the given implementation.
 pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: DefId)
                       -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(impl_def_id.krate);
-    decoder::get_impl_items(&*cdata, impl_def_id.xxx_node)
+    decoder::get_impl_items(&*cdata, impl_def_id.index)
 }
 
 pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@@ -128,7 +128,7 @@ pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
     let cdata = tcx.sess.cstore.get_crate_data(def.krate);
     decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
                                     &*cdata,
-                                    def.xxx_node,
+                                    def.index,
                                     tcx)
 }
 
@@ -136,24 +136,24 @@ pub fn get_trait_name(cstore: &cstore::CStore, def: DefId) -> ast::Name {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_trait_name(cstore.intr.clone(),
                             &*cdata,
-                            def.xxx_node)
+                            def.index)
 }
 
 pub fn is_static_method(cstore: &cstore::CStore, def: DefId) -> bool {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::is_static_method(&*cdata, def.xxx_node)
+    decoder::is_static_method(&*cdata, def.index)
 }
 
 pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: DefId)
                               -> Vec<ty::ImplOrTraitItemId> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_item_def_ids(&*cdata, def.xxx_node)
+    decoder::get_trait_item_def_ids(&*cdata, def.index)
 }
 
 pub fn get_item_variances(cstore: &cstore::CStore,
                           def: DefId) -> ty::ItemVariances {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_item_variances(&*cdata, def.xxx_node)
+    decoder::get_item_variances(&*cdata, def.index)
 }
 
 pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
@@ -161,43 +161,43 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
                                         -> Vec<Rc<ty::Method<'tcx>>> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.xxx_node, tcx)
+    decoder::get_provided_trait_methods(cstore.intr.clone(), &*cdata, def.index, tcx)
 }
 
 pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
                                    -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.xxx_node, tcx)
+    decoder::get_associated_consts(cstore.intr.clone(), &*cdata, def.index, tcx)
 }
 
 pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: DefId)
                           -> Option<ast::Name> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_type_name_if_impl(&*cdata, def.xxx_node)
+    decoder::get_type_name_if_impl(&*cdata, def.index)
 }
 
 pub fn get_methods_if_impl(cstore: &cstore::CStore,
                                   def: DefId)
                                -> Option<Vec<MethodInfo> > {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.xxx_node)
+    decoder::get_methods_if_impl(cstore.intr.clone(), &*cdata, def.index)
 }
 
 pub fn get_item_attrs(cstore: &cstore::CStore,
                       def_id: DefId)
                       -> Vec<ast::Attribute> {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_item_attrs(&*cdata, def_id.xxx_node)
+    decoder::get_item_attrs(&*cdata, def_id.index)
 }
 
 pub fn get_struct_field_names(cstore: &cstore::CStore, def: DefId) -> Vec<ast::Name> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_struct_field_names(&cstore.intr, &*cdata, def.xxx_node)
+    decoder::get_struct_field_names(&cstore.intr, &*cdata, def.index)
 }
 
-pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId) -> FnvHashMap<ast::NodeId,
-        Vec<ast::Attribute>> {
+pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId)
+                              -> FnvHashMap<DefId, Vec<ast::Attribute>> {
     let cdata = cstore.get_crate_data(def.krate);
     decoder::get_struct_field_attrs(&*cdata)
 }
@@ -207,19 +207,19 @@ pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>,
                       -> ty::TypeScheme<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_type(&*cdata, def.xxx_node, tcx)
+    decoder::get_type(&*cdata, def.index, tcx)
 }
 
 pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TraitDef<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_trait_def(&*cdata, def.xxx_node, tcx)
+    decoder::get_trait_def(&*cdata, def.index, tcx)
 }
 
 pub fn get_adt_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_adt_def(&cstore.intr, &*cdata, def.xxx_node, tcx)
+    decoder::get_adt_def(&cstore.intr, &*cdata, def.index, tcx)
 }
 
 pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@@ -227,7 +227,7 @@ pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_predicates(&*cdata, def.xxx_node, tcx)
+    decoder::get_predicates(&*cdata, def.index, tcx)
 }
 
 pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@@ -235,7 +235,7 @@ pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_super_predicates(&*cdata, def.xxx_node, tcx)
+    decoder::get_super_predicates(&*cdata, def.index, tcx)
 }
 
 pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
@@ -244,7 +244,7 @@ pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_impl_polarity(&*cdata, def.xxx_node)
+    decoder::get_impl_polarity(&*cdata, def.index)
 }
 
 pub fn get_custom_coerce_unsized_kind<'tcx>(
@@ -254,7 +254,7 @@ pub fn get_custom_coerce_unsized_kind<'tcx>(
 {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_custom_coerce_unsized_kind(&*cdata, def.xxx_node)
+    decoder::get_custom_coerce_unsized_kind(&*cdata, def.index)
 }
 
 // Given a def_id for an impl, return the trait it implements,
@@ -264,7 +264,7 @@ pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
                             -> Option<ty::TraitRef<'tcx>> {
     let cstore = &tcx.sess.cstore;
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_impl_trait(&*cdata, def.xxx_node, tcx)
+    decoder::get_impl_trait(&*cdata, def.index, tcx)
 }
 
 pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
@@ -279,7 +279,7 @@ pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore,
     F: FnMut(DefId),
 {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::each_inherent_implementation_for_type(&*cdata, def_id.xxx_node, callback)
+    decoder::each_inherent_implementation_for_type(&*cdata, def_id.index, callback)
 }
 
 pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
@@ -300,7 +300,7 @@ pub fn get_trait_of_item(cstore: &cstore::CStore,
                          tcx: &ty::ctxt)
                          -> Option<DefId> {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_trait_of_item(&*cdata, def_id.xxx_node, tcx)
+    decoder::get_trait_of_item(&*cdata, def_id.index, tcx)
 }
 
 pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
@@ -308,7 +308,7 @@ pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
     -> Option<DefId>
 {
     let cdata = cstore.get_crate_data(def_id.krate);
-    decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.xxx_node)
+    decoder::get_tuple_struct_definition_if_ctor(&*cdata, def_id.index)
 }
 
 pub fn get_dylib_dependency_formats(cstore: &cstore::CStore,
@@ -330,7 +330,7 @@ pub fn get_method_arg_names(cstore: &cstore::CStore, did: DefId)
     -> Vec<String>
 {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::get_method_arg_names(&*cdata, did.xxx_node)
+    decoder::get_method_arg_names(&*cdata, did.index)
 }
 
 pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
@@ -342,24 +342,24 @@ pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
 
 pub fn is_typedef(cstore: &cstore::CStore, did: DefId) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_typedef(&*cdata, did.xxx_node)
+    decoder::is_typedef(&*cdata, did.index)
 }
 
 pub fn is_const_fn(cstore: &cstore::CStore, did: DefId) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_const_fn(&*cdata, did.xxx_node)
+    decoder::is_const_fn(&*cdata, did.index)
 }
 
 pub fn is_impl(cstore: &cstore::CStore, did: DefId) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_impl(&*cdata, did.xxx_node)
+    decoder::is_impl(&*cdata, did.index)
 }
 
 pub fn get_stability(cstore: &cstore::CStore,
                      def: DefId)
                      -> Option<attr::Stability> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_stability(&*cdata, def.xxx_node)
+    decoder::get_stability(&*cdata, def.index)
 }
 
 pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool {
@@ -369,21 +369,42 @@ pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool {
 pub fn get_repr_attrs(cstore: &cstore::CStore, def: DefId)
                       -> Vec<attr::ReprAttr> {
     let cdata = cstore.get_crate_data(def.krate);
-    decoder::get_repr_attrs(&*cdata, def.xxx_node)
+    decoder::get_repr_attrs(&*cdata, def.index)
 }
 
 pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: DefId) -> bool {
     let cdata = cstore.get_crate_data(trait_def_id.krate);
-    decoder::is_defaulted_trait(&*cdata, trait_def_id.xxx_node)
+    decoder::is_defaulted_trait(&*cdata, trait_def_id.index)
 }
 
 pub fn is_default_impl(cstore: &cstore::CStore, impl_did: DefId) -> bool {
     let cdata = cstore.get_crate_data(impl_did.krate);
-    decoder::is_default_impl(&*cdata, impl_did.xxx_node)
+    decoder::is_default_impl(&*cdata, impl_did.index)
 }
 
 pub fn is_extern_fn(cstore: &cstore::CStore, did: DefId,
                     tcx: &ty::ctxt) -> bool {
     let cdata = cstore.get_crate_data(did.krate);
-    decoder::is_extern_fn(&*cdata, did.xxx_node, tcx)
+    decoder::is_extern_fn(&*cdata, did.index, tcx)
 }
+
+pub fn closure_kind<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureKind {
+    assert!(!def_id.is_local());
+    let cdata = tcx.sess.cstore.get_crate_data(def_id.krate);
+    decoder::closure_kind(&*cdata, def_id.index)
+}
+
+pub fn closure_ty<'tcx>(tcx: &ty::ctxt<'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> {
+    assert!(!def_id.is_local());
+    let cdata = tcx.sess.cstore.get_crate_data(def_id.krate);
+    decoder::closure_ty(&*cdata, def_id.index, tcx)
+}
+
+pub fn def_path(tcx: &ty::ctxt, def: DefId) -> ast_map::DefPath {
+    let cstore = &tcx.sess.cstore;
+    let cdata = cstore.get_crate_data(def.krate);
+    let path = decoder::def_path(&*cdata, def.index);
+    let local_path = cdata.local_def_path();
+    local_path.into_iter().chain(path).collect()
+}
+
index 915027041bc4447f0b5d1173c094cb3e2edca829..48676a2a1b48ab51f573d63cb5043bf07c08feea 100644 (file)
@@ -59,6 +59,7 @@ pub struct ImportedFileMap {
 pub struct crate_metadata {
     pub name: String,
     pub local_path: RefCell<SmallVector<ast_map::PathElem>>,
+    pub local_def_path: RefCell<ast_map::DefPath>,
     pub data: MetadataBlob,
     pub cnum_map: RefCell<cnum_map>,
     pub cnum: ast::CrateNum,
@@ -312,6 +313,23 @@ pub fn update_local_path<'a, 'b>(&self, candidate: ast_map::PathElems<'a, 'b>) {
         }
     }
 
+    pub fn local_def_path(&self) -> ast_map::DefPath {
+        let local_def_path = self.local_def_path.borrow();
+        if local_def_path.is_empty() {
+            let name = ast_map::DefPathData::DetachedCrate(token::intern(&self.name));
+            vec![ast_map::DisambiguatedDefPathData { data: name, disambiguator: 0 }]
+        } else {
+            local_def_path.clone()
+        }
+    }
+
+    pub fn update_local_def_path(&self, candidate: ast_map::DefPath) {
+        let mut local_def_path = self.local_def_path.borrow_mut();
+        if local_def_path.is_empty() || candidate.len() < local_def_path.len() {
+            *local_def_path = candidate;
+        }
+    }
+
     pub fn is_allocator(&self) -> bool {
         let attrs = decoder::get_crate_attributes(self.data());
         attr::contains_name(&attrs, "allocator")
index 8ce31e533de8245de49f288247324fc0658719de..58e87f1910a68e2fe5ee01f9673607576fa685d4 100644 (file)
@@ -30,7 +30,7 @@
 use metadata::inline::InlinedItem;
 use metadata::tydecode::TyDecoder;
 use middle::def;
-use middle::def_id::DefId;
+use middle::def_id::{DefId, DefIndex};
 use middle::lang_items;
 use middle::subst;
 use middle::ty::{ImplContainer, TraitContainer};
 pub type Cmd<'a> = &'a crate_metadata;
 
 impl crate_metadata {
-    fn get_item(&self, item_id: ast::NodeId) -> Option<rbml::Doc> {
+    fn get_item(&self, item_id: DefIndex) -> Option<rbml::Doc> {
         self.index.lookup_item(self.data(), item_id).map(|pos| {
             reader::doc_at(self.data(), pos as usize).unwrap().doc
         })
     }
 
-    fn lookup_item(&self, item_id: ast::NodeId) -> rbml::Doc {
+    fn lookup_item(&self, item_id: DefIndex) -> rbml::Doc {
         match self.get_item(item_id) {
-            None => panic!("lookup_item: id not found: {}", item_id),
+            None => panic!("lookup_item: id not found: {:?}", item_id),
             Some(d) => d
         }
     }
@@ -75,7 +75,7 @@ fn lookup_item(&self, item_id: ast::NodeId) -> rbml::Doc {
 
 pub fn load_index(data: &[u8]) -> index::Index {
     let index = reader::get_doc(rbml::Doc::new(data), tag_index);
-    index::Index::from_buf(index.data, index.start, index.end)
+    index::Index::from_rbml(index)
 }
 
 pub fn crate_rustc_version(data: &[u8]) -> Option<String> {
@@ -170,7 +170,8 @@ fn item_symbol(item: rbml::Doc) -> String {
 
 fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
     let id = reader::doc_as_u64(d);
-    let def_id = DefId { krate: (id >> 32) as u32, xxx_node: id as u32 };
+    let index = DefIndex::new((id & 0xFFFF_FFFF) as usize);
+    let def_id = DefId { krate: (id >> 32) as u32, index: index };
     translate_def_id(cdata, def_id)
 }
 
@@ -203,14 +204,14 @@ fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> {
 fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> {
     let tp = reader::get_doc(doc, tag_items_data_item_type);
     TyDecoder::with_doc(tcx, cdata.cnum, tp,
-                        &mut |_, did| translate_def_id(cdata, did))
+                        &mut |did| translate_def_id(cdata, did))
         .parse_ty()
 }
 
 fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Option<Ty<'tcx>> {
     reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| {
         TyDecoder::with_doc(tcx, cdata.cnum, tp,
-                            &mut |_, did| translate_def_id(cdata, did))
+                            &mut |did| translate_def_id(cdata, did))
             .parse_ty()
     })
 }
@@ -219,7 +220,7 @@ fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
                         cdata: Cmd) -> ty::BareFnTy<'tcx> {
     let tp = reader::get_doc(doc, tag_item_method_fty);
     TyDecoder::with_doc(tcx, cdata.cnum, tp,
-                        &mut |_, did| translate_def_id(cdata, did))
+                        &mut |did| translate_def_id(cdata, did))
         .parse_bare_fn_ty()
 }
 
@@ -231,7 +232,7 @@ pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc,
 fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
                        -> ty::TraitRef<'tcx> {
     TyDecoder::with_doc(tcx, cdata.cnum, doc,
-                        &mut |_, did| translate_def_id(cdata, did))
+                        &mut |did| translate_def_id(cdata, did))
         .parse_trait_ref()
 }
 
@@ -345,7 +346,7 @@ fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
 }
 
 pub fn get_trait_def<'tcx>(cdata: Cmd,
-                           item_id: ast::NodeId,
+                           item_id: DefIndex,
                            tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
 {
     let item_doc = cdata.lookup_item(item_id);
@@ -368,7 +369,7 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
 
 pub fn get_adt_def<'tcx>(intr: &IdentInterner,
                          cdata: Cmd,
-                         item_id: ast::NodeId,
+                         item_id: DefIndex,
                          tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx>
 {
     fn get_enum_variants<'tcx>(intr: &IdentInterner,
@@ -378,7 +379,7 @@ fn get_enum_variants<'tcx>(intr: &IdentInterner,
         let mut disr_val = 0;
         reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| {
             let did = translated_def_id(cdata, p);
-            let item = cdata.lookup_item(did.xxx_node);
+            let item = cdata.lookup_item(did.index);
 
             if let Some(disr) = variant_disr_val(item) {
                 disr_val = disr;
@@ -428,7 +429,7 @@ fn get_struct_variant<'tcx>(intr: &IdentInterner,
     }
 
     let doc = cdata.lookup_item(item_id);
-    let did = DefId { krate: cdata.cnum, xxx_node: item_id };
+    let did = DefId { krate: cdata.cnum, index: item_id };
     let (kind, variants) = match item_family(doc) {
         Enum => (ty::AdtKind::Enum,
                  get_enum_variants(intr, cdata, doc, tcx)),
@@ -448,7 +449,7 @@ fn get_struct_variant<'tcx>(intr: &IdentInterner,
             // from the ctor.
             debug!("evaluating the ctor-type of {:?}",
                    variant.name);
-            let ctor_ty = get_type(cdata, variant.did.xxx_node, tcx).ty;
+            let ctor_ty = get_type(cdata, variant.did.index, tcx).ty;
             debug!("evaluating the ctor-type of {:?}.. {:?}",
                    variant.name,
                    ctor_ty);
@@ -468,7 +469,7 @@ fn get_struct_variant<'tcx>(intr: &IdentInterner,
         } else {
             for field in &variant.fields {
                 debug!("evaluating the type of {:?}::{:?}", variant.name, field.name);
-                let ty = get_type(cdata, field.did.xxx_node, tcx).ty;
+                let ty = get_type(cdata, field.did.index, tcx).ty;
                 field.fulfill_ty(ty);
                 debug!("evaluating the type of {:?}::{:?}: {:?}",
                        variant.name, field.name, ty);
@@ -480,7 +481,7 @@ fn get_struct_variant<'tcx>(intr: &IdentInterner,
 }
 
 pub fn get_predicates<'tcx>(cdata: Cmd,
-                            item_id: ast::NodeId,
+                            item_id: DefIndex,
                             tcx: &ty::ctxt<'tcx>)
                             -> ty::GenericPredicates<'tcx>
 {
@@ -489,7 +490,7 @@ pub fn get_predicates<'tcx>(cdata: Cmd,
 }
 
 pub fn get_super_predicates<'tcx>(cdata: Cmd,
-                                  item_id: ast::NodeId,
+                                  item_id: DefIndex,
                                   tcx: &ty::ctxt<'tcx>)
                                   -> ty::GenericPredicates<'tcx>
 {
@@ -497,11 +498,11 @@ pub fn get_super_predicates<'tcx>(cdata: Cmd,
     doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates)
 }
 
-pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
+pub fn get_type<'tcx>(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt<'tcx>)
                       -> ty::TypeScheme<'tcx>
 {
     let item_doc = cdata.lookup_item(id);
-    let t = item_type(DefId { krate: cdata.cnum, xxx_node: id }, item_doc, tcx,
+    let t = item_type(DefId { krate: cdata.cnum, index: id }, item_doc, tcx,
                       cdata);
     let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
     ty::TypeScheme {
@@ -510,7 +511,7 @@ pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
     }
 }
 
-pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> {
+pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> {
     let item = cdata.lookup_item(id);
     reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| {
         let mut decoder = reader::Decoder::new(doc);
@@ -518,7 +519,7 @@ pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> {
     })
 }
 
-pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
+pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec<attr::ReprAttr> {
     let item = cdata.lookup_item(id);
     match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| {
         let mut decoder = reader::Decoder::new(doc);
@@ -530,7 +531,7 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
 }
 
 pub fn get_impl_polarity<'tcx>(cdata: Cmd,
-                               id: ast::NodeId)
+                               id: DefIndex)
                                -> Option<hir::ImplPolarity>
 {
     let item_doc = cdata.lookup_item(id);
@@ -545,7 +546,7 @@ pub fn get_impl_polarity<'tcx>(cdata: Cmd,
 
 pub fn get_custom_coerce_unsized_kind<'tcx>(
     cdata: Cmd,
-    id: ast::NodeId)
+    id: DefIndex)
     -> Option<ty::adjustment::CustomCoerceUnsized>
 {
     let item_doc = cdata.lookup_item(id);
@@ -556,7 +557,7 @@ pub fn get_custom_coerce_unsized_kind<'tcx>(
 }
 
 pub fn get_impl_trait<'tcx>(cdata: Cmd,
-                            id: ast::NodeId,
+                            id: DefIndex,
                             tcx: &ty::ctxt<'tcx>)
                             -> Option<ty::TraitRef<'tcx>>
 {
@@ -572,12 +573,12 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
     }
 }
 
-pub fn get_symbol(cdata: Cmd, id: ast::NodeId) -> String {
+pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
     return item_symbol(cdata.lookup_item(id));
 }
 
 /// If you have a crate_metadata, call get_symbol instead
-pub fn get_symbol_from_buf(data: &[u8], id: ast::NodeId) -> String {
+pub fn get_symbol_from_buf(data: &[u8], id: DefIndex) -> String {
     let index = load_index(data);
     let pos = index.lookup_item(data, id).unwrap();
     let doc = reader::doc_at(data, pos as usize).unwrap().doc;
@@ -594,18 +595,17 @@ pub enum DefLike {
 
 /// Iterates over the language items in the given crate.
 pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where
-    F: FnMut(ast::NodeId, usize) -> bool,
+    F: FnMut(DefIndex, usize) -> bool,
 {
     let root = rbml::Doc::new(cdata.data());
     let lang_items = reader::get_doc(root, tag_lang_items);
     reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| {
         let id_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
         let id = reader::doc_as_u32(id_doc) as usize;
-        let node_id_doc = reader::get_doc(item_doc,
-                                          tag_lang_items_item_node_id);
-        let node_id = reader::doc_as_u32(node_id_doc) as ast::NodeId;
+        let index_doc = reader::get_doc(item_doc, tag_lang_items_item_index);
+        let index = DefIndex::from_u32(reader::doc_as_u32(index_doc));
 
-        f(node_id, id)
+        f(index, id)
     })
 }
 
@@ -634,7 +634,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
         };
 
         // Get the item.
-        match crate_data.get_item(child_def_id.xxx_node) {
+        match crate_data.get_item(child_def_id.index) {
             None => {}
             Some(child_item_doc) => {
                 // Hand off the item to the callback.
@@ -652,12 +652,12 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
     for inherent_impl_def_id_doc in reader::tagged_docs(item_doc,
                                                              tag_items_data_item_inherent_impl) {
         let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata);
-        if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.xxx_node) {
+        if let Some(inherent_impl_doc) = cdata.get_item(inherent_impl_def_id.index) {
             for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc,
                                                                  tag_item_impl_item) {
                 let impl_item_def_id = item_def_id(impl_item_def_id_doc,
                                                    cdata);
-                if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.xxx_node) {
+                if let Some(impl_method_doc) = cdata.get_item(impl_item_def_id.index) {
                     if let StaticMethod = item_family(impl_method_doc) {
                         // Hand off the static method to the callback.
                         let static_method_name = item_name(&*intr, impl_method_doc);
@@ -693,7 +693,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
         };
 
         // Get the item.
-        if let Some(child_item_doc) = crate_data.get_item(child_def_id.xxx_node) {
+        if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) {
             // Hand off the item to the callback.
             let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id);
             // These items have a public visibility because they're part of
@@ -706,7 +706,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
 /// Iterates over each child of the given item.
 pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
                                cdata: Cmd,
-                               id: ast::NodeId,
+                               id: DefIndex,
                                get_crate_data: G,
                                callback: F) where
     F: FnMut(DefLike, ast::Name, hir::Visibility),
@@ -745,11 +745,11 @@ pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
                                 callback)
 }
 
-pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec<hir_map::PathElem> {
+pub fn get_item_path(cdata: Cmd, id: DefIndex) -> Vec<hir_map::PathElem> {
     item_path(cdata.lookup_item(id))
 }
 
-pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId) -> ast::Name {
+pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: DefIndex) -> ast::Name {
     item_name(intr, cdata.lookup_item(id))
 }
 
@@ -757,22 +757,25 @@ pub fn get_item_name(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId) -> ast::
     Box<for<'tcx> FnMut(Cmd,
                         &ty::ctxt<'tcx>,
                         Vec<hir_map::PathElem>,
+                        hir_map::DefPath,
                         rbml::Doc)
-                        -> Result<&'tcx InlinedItem, Vec<hir_map::PathElem>> + 'a>;
+                        -> 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: ast::NodeId,
+pub fn maybe_get_item_ast<'tcx>(cdata: Cmd, tcx: &ty::ctxt<'tcx>, id: DefIndex,
                                 mut decode_inlined_item: DecodeInlinedItem)
                                 -> csearch::FoundAst<'tcx> {
-    debug!("Looking up item: {}", id);
+    debug!("Looking up item: {:?}", id);
     let item_doc = cdata.lookup_item(id);
     let path = item_path(item_doc).split_last().unwrap().1.to_vec();
-    match decode_inlined_item(cdata, tcx, path, item_doc) {
+    let def_path = def_path(cdata, id);
+    match decode_inlined_item(cdata, tcx, path, def_path, item_doc) {
         Ok(ii) => csearch::FoundAst::Found(ii),
-        Err(path) => {
+        Err((path, def_path)) => {
             match item_parent_item(cdata, item_doc) {
                 Some(did) => {
-                    let parent_item = cdata.lookup_item(did.xxx_node);
-                    match decode_inlined_item(cdata, tcx, path, parent_item) {
+                    let parent_item = cdata.lookup_item(did.index);
+                    match decode_inlined_item(cdata, tcx, path, def_path, parent_item) {
                         Ok(ii) => csearch::FoundAst::FoundParent(did, ii),
                         Err(_) => csearch::FoundAst::NotFound
                     }
@@ -811,7 +814,7 @@ fn get_mutability(ch: u8) -> hir::Mutability {
 }
 
 /// Returns the def IDs of all the items in the given implementation.
-pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
+pub fn get_impl_items(cdata: Cmd, impl_id: DefIndex)
                       -> Vec<ty::ImplOrTraitItemId> {
     reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| {
         let def_id = item_def_id(doc, cdata);
@@ -826,13 +829,13 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
 
 pub fn get_trait_name(intr: Rc<IdentInterner>,
                       cdata: Cmd,
-                      id: ast::NodeId)
+                      id: DefIndex)
                       -> ast::Name {
     let doc = cdata.lookup_item(id);
     item_name(&*intr, doc)
 }
 
-pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool {
+pub fn is_static_method(cdata: Cmd, id: DefIndex) -> bool {
     let doc = cdata.lookup_item(id);
     match item_sort(doc) {
         Some('r') | Some('p') => {
@@ -844,7 +847,7 @@ pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool {
 
 pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
                                     cdata: Cmd,
-                                    id: ast::NodeId,
+                                    id: DefIndex,
                                     tcx: &ty::ctxt<'tcx>)
                                     -> ty::ImplOrTraitItem<'tcx> {
     let item_doc = cdata.lookup_item(id);
@@ -852,7 +855,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
     let def_id = item_def_id(item_doc, cdata);
 
     let container_id = item_require_parent_item(cdata, item_doc);
-    let container_doc = cdata.lookup_item(container_id.xxx_node);
+    let container_doc = cdata.lookup_item(container_id.index);
     let container = match item_family(container_doc) {
         Trait => TraitContainer(container_id),
         _ => ImplContainer(container_id),
@@ -902,7 +905,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
     }
 }
 
-pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
+pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex)
                               -> Vec<ty::ImplOrTraitItemId> {
     let item = cdata.lookup_item(id);
     reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
@@ -916,7 +919,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
     }).collect()
 }
 
-pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
+pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> ty::ItemVariances {
     let item_doc = cdata.lookup_item(id);
     let variance_doc = reader::get_doc(item_doc, tag_item_variances);
     let mut decoder = reader::Decoder::new(variance_doc);
@@ -925,19 +928,19 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
 
 pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
                                         cdata: Cmd,
-                                        id: ast::NodeId,
+                                        id: DefIndex,
                                         tcx: &ty::ctxt<'tcx>)
                                         -> Vec<Rc<ty::Method<'tcx>>> {
     let item = cdata.lookup_item(id);
 
     reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
         let did = item_def_id(mth_id, cdata);
-        let mth = cdata.lookup_item(did.xxx_node);
+        let mth = cdata.lookup_item(did.index);
 
         if item_sort(mth) == Some('p') {
             let trait_item = get_impl_or_trait_item(intr.clone(),
                                                     cdata,
-                                                    did.xxx_node,
+                                                    did.index,
                                                     tcx);
             if let ty::MethodTraitItem(ref method) = trait_item {
                 Some((*method).clone())
@@ -952,7 +955,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
 
 pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
                                    cdata: Cmd,
-                                   id: ast::NodeId,
+                                   id: DefIndex,
                                    tcx: &ty::ctxt<'tcx>)
                                    -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
     let item = cdata.lookup_item(id);
@@ -960,13 +963,13 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
     [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
         reader::tagged_docs(item, tag).filter_map(|ac_id| {
             let did = item_def_id(ac_id, cdata);
-            let ac_doc = cdata.lookup_item(did.xxx_node);
+            let ac_doc = cdata.lookup_item(did.index);
 
             match item_sort(ac_doc) {
                 Some('C') | Some('c') => {
                     let trait_item = get_impl_or_trait_item(intr.clone(),
                                                             cdata,
-                                                            did.xxx_node,
+                                                            did.index,
                                                             tcx);
                     if let ty::ConstTraitItem(ref ac) = trait_item {
                         Some((*ac).clone())
@@ -981,7 +984,7 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
 }
 
 pub fn get_type_name_if_impl(cdata: Cmd,
-                             node_id: ast::NodeId) -> Option<ast::Name> {
+                             node_id: DefIndex) -> Option<ast::Name> {
     let item = cdata.lookup_item(node_id);
     if item_family(item) != Impl {
         return None;
@@ -994,7 +997,7 @@ pub fn get_type_name_if_impl(cdata: Cmd,
 
 pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
                                   cdata: Cmd,
-                                  node_id: ast::NodeId)
+                                  node_id: DefIndex)
                                -> Option<Vec<MethodInfo> > {
     let item = cdata.lookup_item(node_id);
     if item_family(item) != Impl {
@@ -1011,7 +1014,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
 
     let mut impl_methods = Vec::new();
     for impl_method_id in impl_method_ids {
-        let impl_method_doc = cdata.lookup_item(impl_method_id.xxx_node);
+        let impl_method_doc = cdata.lookup_item(impl_method_id.index);
         let family = item_family(impl_method_doc);
         match family {
             StaticMethod | Method => {
@@ -1031,7 +1034,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
 /// If node_id is the constructor of a tuple struct, retrieve the NodeId of
 /// the actual type definition, otherwise, return None
 pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
-                                           node_id: ast::NodeId)
+                                           node_id: DefIndex)
     -> Option<DefId>
 {
     let item = cdata.lookup_item(node_id);
@@ -1041,24 +1044,24 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
 }
 
 pub fn get_item_attrs(cdata: Cmd,
-                      orig_node_id: ast::NodeId)
+                      orig_node_id: DefIndex)
                       -> Vec<ast::Attribute> {
     // The attributes for a tuple struct are attached to the definition, not the ctor;
     // we assume that someone passing in a tuple struct ctor is actually wanting to
     // look at the definition
     let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id);
-    let node_id = node_id.map(|x| x.xxx_node).unwrap_or(orig_node_id);
+    let node_id = node_id.map(|x| x.index).unwrap_or(orig_node_id);
     let item = cdata.lookup_item(node_id);
     get_attributes(item)
 }
 
-pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap<ast::NodeId, Vec<ast::Attribute>> {
+pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap<DefId, Vec<ast::Attribute>> {
     let data = rbml::Doc::new(cdata.data());
     let fields = reader::get_doc(data, tag_struct_fields);
     reader::tagged_docs(fields, tag_struct_field).map(|field| {
-        let id = reader::doc_as_u32(reader::get_doc(field, tag_struct_field_id));
+        let def_id = translated_def_id(cdata, reader::get_doc(field, tag_def_id));
         let attrs = get_attributes(field);
-        (id, attrs)
+        (def_id, attrs)
     }).collect()
 }
 
@@ -1070,7 +1073,7 @@ fn struct_field_family_to_visibility(family: Family) -> hir::Visibility {
     }
 }
 
-pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId)
+pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: DefIndex)
     -> Vec<ast::Name> {
     let item = cdata.lookup_item(id);
     reader::tagged_docs(item, tag_item_field).map(|an_item| {
@@ -1228,14 +1231,14 @@ pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()>
 // crate to the correct local crate number.
 pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
     if did.is_local() {
-        return DefId { krate: cdata.cnum, xxx_node: did.xxx_node };
+        return DefId { krate: cdata.cnum, index: did.index };
     }
 
     match cdata.cnum_map.borrow().get(&did.krate) {
         Some(&n) => {
             DefId {
                 krate: n,
-                xxx_node: did.xxx_node,
+                index: did.index,
             }
         }
         None => panic!("didn't find a crate in the cnum_map")
@@ -1246,12 +1249,12 @@ pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
 // for an external crate.
 fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
     if did.krate == cdata.cnum {
-        return Some(DefId { krate: LOCAL_CRATE, xxx_node: did.xxx_node });
+        return Some(DefId { krate: LOCAL_CRATE, index: did.index });
     }
 
     for (&local, &global) in cdata.cnum_map.borrow().iter() {
         if global == did.krate {
-            return Some(DefId { krate: local, xxx_node: did.xxx_node });
+            return Some(DefId { krate: local, index: did.index });
         }
     }
 
@@ -1259,7 +1262,7 @@ fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
 }
 
 pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
-                                                id: ast::NodeId,
+                                                id: DefIndex,
                                                 mut callback: F)
     where F: FnMut(DefId),
 {
@@ -1277,7 +1280,7 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
     F: FnMut(DefId),
 {
     if cdata.cnum == def_id.krate {
-        let item_doc = cdata.lookup_item(def_id.xxx_node);
+        let item_doc = cdata.lookup_item(def_id.index);
         for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) {
             callback(item_def_id(impl_doc, cdata));
         }
@@ -1299,14 +1302,14 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
     }
 }
 
-pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt)
+pub fn get_trait_of_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt)
                          -> Option<DefId> {
     let item_doc = cdata.lookup_item(id);
     let parent_item_id = match item_parent_item(cdata, item_doc) {
         None => return None,
         Some(item_id) => item_id,
     };
-    let parent_item_doc = cdata.lookup_item(parent_item_id.xxx_node);
+    let parent_item_doc = cdata.lookup_item(parent_item_id.index);
     match item_family(parent_item_doc) {
         Trait => Some(item_def_id(parent_item_doc, cdata)),
         Impl | DefaultImpl => {
@@ -1332,9 +1335,9 @@ pub fn get_native_libraries(cdata: Cmd)
     }).collect()
 }
 
-pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<ast::NodeId> {
+pub fn get_plugin_registrar_fn(data: &[u8]) -> Option<DefIndex> {
     reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn)
-        .map(|doc| reader::doc_as_u32(doc))
+        .map(|doc| DefIndex::from_u32(reader::doc_as_u32(doc)))
 }
 
 pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
@@ -1386,7 +1389,7 @@ pub fn get_missing_lang_items(cdata: Cmd)
     }).collect()
 }
 
-pub fn get_method_arg_names(cdata: Cmd, id: ast::NodeId) -> Vec<String> {
+pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec<String> {
     let method_doc = cdata.lookup_item(id);
     match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
         Some(args_doc) => {
@@ -1404,12 +1407,12 @@ pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> {
     reader::tagged_docs(items, tag_reachable_id).map(|doc| {
         DefId {
             krate: cdata.cnum,
-            xxx_node: reader::doc_as_u32(doc),
+            index: DefIndex::from_u32(reader::doc_as_u32(doc)),
         }
     }).collect()
 }
 
-pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
+pub fn is_typedef(cdata: Cmd, id: DefIndex) -> bool {
     let item_doc = cdata.lookup_item(id);
     match item_family(item_doc) {
         Type => true,
@@ -1417,7 +1420,7 @@ pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
     }
 }
 
-pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool {
+pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
     let item_doc = cdata.lookup_item(id);
     match fn_constness(item_doc) {
         hir::Constness::Const => true,
@@ -1425,7 +1428,7 @@ pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool {
     }
 }
 
-pub fn is_impl(cdata: Cmd, id: ast::NodeId) -> bool {
+pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
     let item_doc = cdata.lookup_item(id);
     match item_family(item_doc) {
         Impl => true,
@@ -1445,7 +1448,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
     for p in reader::tagged_docs(doc, tag_type_param_def) {
         let bd =
             TyDecoder::with_doc(tcx, cdata.cnum, p,
-                                &mut |_, did| translate_def_id(cdata, did))
+                                &mut |did| translate_def_id(cdata, did))
             .parse_type_param_def();
         types.push(bd.space, bd);
     }
@@ -1467,7 +1470,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
 
         let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| {
             TyDecoder::with_doc(tcx, cdata.cnum, p,
-                                &mut |_, did| translate_def_id(cdata, did))
+                                &mut |did| translate_def_id(cdata, did))
             .parse_region()
         }).collect();
 
@@ -1497,7 +1500,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc,
         let data_doc = reader::get_doc(predicate_doc, tag_predicate_data);
         let data =
             TyDecoder::with_doc(tcx, cdata.cnum, data_doc,
-                                &mut |_, did| translate_def_id(cdata, did))
+                                &mut |did| translate_def_id(cdata, did))
             .parse_predicate();
 
         predicates.push(space, data);
@@ -1506,14 +1509,14 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc,
     ty::GenericPredicates { predicates: predicates }
 }
 
-pub fn is_defaulted_trait(cdata: Cmd, trait_id: ast::NodeId) -> bool {
+pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool {
     let trait_doc = cdata.lookup_item(trait_id);
     assert!(item_family(trait_doc) == Family::Trait);
     let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
     reader::doc_as_u8(defaulted_doc) != 0
 }
 
-pub fn is_default_impl(cdata: Cmd, impl_id: ast::NodeId) -> bool {
+pub fn is_default_impl(cdata: Cmd, impl_id: DefIndex) -> bool {
     let impl_doc = cdata.lookup_item(impl_id);
     item_family(impl_doc) == Family::DefaultImpl
 }
@@ -1528,7 +1531,7 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
     }).collect()
 }
 
-pub fn is_extern_fn(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> bool {
+pub fn is_extern_fn(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt) -> bool {
     let item_doc = match cdata.get_item(id) {
         Some(doc) => doc,
         None => return false,
@@ -1543,3 +1546,42 @@ pub fn is_extern_fn(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> bool {
         false
     }
 }
+
+pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind {
+    let closure_doc = cdata.lookup_item(closure_id);
+    let closure_kind_doc = reader::get_doc(closure_doc, tag_items_closure_kind);
+    let mut decoder = reader::Decoder::new(closure_kind_doc);
+    ty::ClosureKind::decode(&mut decoder).unwrap()
+}
+
+pub fn closure_ty<'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: &ty::ctxt<'tcx>)
+                        -> ty::ClosureTy<'tcx> {
+    let closure_doc = cdata.lookup_item(closure_id);
+    let closure_ty_doc = reader::get_doc(closure_doc, tag_items_closure_ty);
+    TyDecoder::with_doc(tcx, cdata.cnum, closure_ty_doc, &mut |did| translate_def_id(cdata, did))
+        .parse_closure_ty()
+}
+
+fn def_key(item_doc: rbml::Doc) -> hir_map::DefKey {
+    match reader::maybe_get_doc(item_doc, tag_def_key) {
+        Some(def_key_doc) => {
+            let mut decoder = reader::Decoder::new(def_key_doc);
+            hir_map::DefKey::decode(&mut decoder).unwrap()
+        }
+        None => {
+            panic!("failed to find block with tag {:?} for item with family {:?}",
+                   tag_def_key,
+                   item_family(item_doc))
+        }
+    }
+}
+
+pub fn def_path(cdata: Cmd, id: DefIndex) -> hir_map::DefPath {
+    debug!("def_path(id={:?})", id);
+    hir_map::definitions::make_def_path(id, |parent| {
+        debug!("def_path: parent={:?}", parent);
+        let parent_doc = cdata.lookup_item(parent);
+        def_key(parent_doc)
+    })
+}
+
index 14e5e8b41ffbb9f0e272f1403eb7fa6b69978049..f637545e2e9109e13b28f3c9b5406c9c5fc12029 100644 (file)
 use metadata::cstore::LOCAL_CRATE;
 use metadata::decoder;
 use metadata::tyencode;
-use metadata::index::{self, IndexEntry};
+use metadata::index::IndexData;
 use metadata::inline::InlinedItemRef;
 use middle::def;
-use middle::def_id::DefId;
+use middle::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::dependency_format::Linkage;
 use middle::stability;
 use middle::ty::{self, Ty};
@@ -34,6 +34,7 @@
 use std::io::prelude::*;
 use std::io::{Cursor, SeekFrom};
 use std::rc::Rc;
+use std::u32;
 use syntax::abi;
 use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
 use syntax::attr;
@@ -93,6 +94,26 @@ fn encode_def_id(rbml_w: &mut Encoder, id: DefId) {
     rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id));
 }
 
+/// For every DefId that we create a metadata item for, we include a
+/// serialized copy of its DefKey, which allows us to recreate a path.
+fn encode_def_id_and_key(ecx: &EncodeContext,
+                         rbml_w: &mut Encoder,
+                         def_id: DefId)
+{
+    encode_def_id(rbml_w, def_id);
+    encode_def_key(ecx, rbml_w, def_id);
+}
+
+fn encode_def_key(ecx: &EncodeContext,
+                  rbml_w: &mut Encoder,
+                  def_id: DefId)
+{
+    rbml_w.start_tag(tag_def_key);
+    let def_key = ecx.tcx.map.def_key(def_id);
+    def_key.encode(rbml_w);
+    rbml_w.end_tag();
+}
+
 fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
                               ecx: &EncodeContext<'a, 'tcx>,
                               trait_ref: ty::TraitRef<'tcx>,
@@ -115,11 +136,12 @@ fn encode_family(rbml_w: &mut Encoder, c: char) {
 }
 
 pub fn def_to_u64(did: DefId) -> u64 {
-    (did.krate as u64) << 32 | (did.xxx_node as u64)
+    assert!(did.index.as_u32() < u32::MAX);
+    (did.krate as u64) << 32 | (did.index.as_usize() as u64)
 }
 
 pub fn def_to_string(did: DefId) -> String {
-    format!("{}:{}", did.krate, did.xxx_node)
+    format!("{}:{}", did.krate, did.index.as_usize())
 }
 
 fn encode_item_variances(rbml_w: &mut Encoder,
@@ -280,7 +302,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
                             rbml_w: &mut Encoder,
                             id: NodeId,
                             vis: hir::Visibility,
-                            index: &mut Vec<IndexEntry>) {
+                            index: &mut IndexData) {
     debug!("encode_enum_variant_info(id={})", id);
 
     let mut disr_val = 0;
@@ -297,12 +319,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
             }
         }
 
-        index.push(IndexEntry {
-            node: vid.xxx_node,
-            pos: rbml_w.mark_stable_position(),
-        });
+        index.record(vid, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, vid);
+        encode_def_id_and_key(ecx, rbml_w, vid);
         encode_family(rbml_w, match variant.kind() {
             ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v',
             ty::VariantKind::Dict => 'V'
@@ -522,7 +541,7 @@ fn encode_info_for_mod(ecx: &EncodeContext,
                        name: Name,
                        vis: hir::Visibility) {
     rbml_w.start_tag(tag_items_data_item);
-    encode_def_id(rbml_w, ecx.tcx.map.local_def_id(id));
+    encode_def_id_and_key(ecx, rbml_w, ecx.tcx.map.local_def_id(id));
     encode_family(rbml_w, 'm');
     encode_name(rbml_w, name);
     debug!("(encoding info for module) encoding info for module ID {}", id);
@@ -631,21 +650,17 @@ fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
 fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                           rbml_w: &mut Encoder,
                           field: ty::FieldDef<'tcx>,
-                          global_index: &mut Vec<IndexEntry>) {
+                          global_index: &mut IndexData) {
     let nm = field.name;
     let id = ecx.local_id(field.did);
 
-    let pos = rbml_w.mark_stable_position();
-    global_index.push(IndexEntry {
-        node: id,
-        pos: pos,
-    });
+    global_index.record(field.did, rbml_w);
     rbml_w.start_tag(tag_items_data_item);
     debug!("encode_field: encoding {} {}", nm, id);
     encode_struct_field_family(rbml_w, field.vis);
     encode_name(rbml_w, nm);
     encode_bounds_and_type_for_item(rbml_w, ecx, id);
-    encode_def_id(rbml_w, ecx.tcx.map.local_def_id(id));
+    encode_def_id_and_key(ecx, rbml_w, field.did);
 
     let stab = stability::lookup(ecx.tcx, field.did);
     encode_stability(rbml_w, stab);
@@ -657,15 +672,14 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
                                rbml_w: &mut Encoder,
                                name: Name,
                                ctor_id: NodeId,
-                               index: &mut Vec<IndexEntry>,
+                               index: &mut IndexData,
                                struct_id: NodeId) {
-    index.push(IndexEntry {
-        node: ctor_id,
-        pos: rbml_w.mark_stable_position(),
-    });
+    let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id);
+
+    index.record(ctor_def_id, rbml_w);
 
     rbml_w.start_tag(tag_items_data_item);
-    encode_def_id(rbml_w, ecx.tcx.map.local_def_id(ctor_id));
+    encode_def_id_and_key(ecx, rbml_w, ctor_def_id);
     encode_family(rbml_w, 'o');
     encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id);
     encode_name(rbml_w, name);
@@ -775,7 +789,7 @@ fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
 fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
                                      rbml_w: &mut Encoder,
                                      method_ty: &ty::Method<'tcx>) {
-    encode_def_id(rbml_w, method_ty.def_id);
+    encode_def_id_and_key(ecx, rbml_w, method_ty.def_id);
     encode_name(rbml_w, method_ty.name);
     encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates,
                     tag_method_ty_generics);
@@ -802,7 +816,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext,
 
     rbml_w.start_tag(tag_items_data_item);
 
-    encode_def_id(rbml_w, associated_const.def_id);
+    encode_def_id_and_key(ecx, rbml_w, associated_const.def_id);
     encode_name(rbml_w, associated_const.name);
     encode_visibility(rbml_w, associated_const.vis);
     encode_family(rbml_w, 'C');
@@ -891,7 +905,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
 
     rbml_w.start_tag(tag_items_data_item);
 
-    encode_def_id(rbml_w, associated_type.def_id);
+    encode_def_id_and_key(ecx, rbml_w, associated_type.def_id);
     encode_name(rbml_w, associated_type.name);
     encode_visibility(rbml_w, associated_type.vis);
     encode_family(rbml_w, 'y');
@@ -1000,19 +1014,11 @@ fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) {
 fn encode_info_for_item(ecx: &EncodeContext,
                         rbml_w: &mut Encoder,
                         item: &hir::Item,
-                        index: &mut Vec<IndexEntry>,
+                        index: &mut IndexData,
                         path: PathElems,
                         vis: hir::Visibility) {
     let tcx = ecx.tcx;
 
-    fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
-                    index: &mut Vec<IndexEntry>) {
-        index.push(IndexEntry {
-            node: item.id,
-            pos: rbml_w.mark_stable_position(),
-        });
-    }
-
     debug!("encoding info for item at {}",
            tcx.sess.codemap().span_to_string(item.span));
 
@@ -1021,9 +1027,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
 
     match item.node {
       hir::ItemStatic(_, m, _) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         if m == hir::MutMutable {
             encode_family(rbml_w, 'b');
         } else {
@@ -1039,9 +1045,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         rbml_w.end_tag();
       }
       hir::ItemConst(_, _) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 'C');
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.name);
@@ -1053,9 +1059,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         rbml_w.end_tag();
       }
       hir::ItemFn(ref decl, _, constness, _, ref generics, _) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, FN_FAMILY);
         let tps_len = generics.ty_params.len();
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
@@ -1076,7 +1082,7 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         rbml_w.end_tag();
       }
       hir::ItemMod(ref m) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         encode_info_for_mod(ecx,
                             rbml_w,
                             m,
@@ -1087,9 +1093,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
                             item.vis);
       }
       hir::ItemForeignMod(ref fm) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 'n');
         encode_name(rbml_w, item.name);
         encode_path(rbml_w, path);
@@ -1104,9 +1110,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         rbml_w.end_tag();
       }
       hir::ItemTy(..) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 'y');
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.name);
@@ -1116,10 +1122,10 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         rbml_w.end_tag();
       }
       hir::ItemEnum(ref enum_definition, _) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
 
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 't');
         encode_item_variances(rbml_w, ecx, item.id);
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
@@ -1154,11 +1160,11 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         }
 
         /* Index the class*/
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
 
         /* Now, make an item for the class itself */
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 'S');
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
 
@@ -1192,9 +1198,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         }
       }
       hir::ItemDefaultImpl(unsafety, _) => {
-          add_to_index(item, rbml_w, index);
+          index.record(def_id, rbml_w);
           rbml_w.start_tag(tag_items_data_item);
-          encode_def_id(rbml_w, def_id);
+          encode_def_id_and_key(ecx, rbml_w, def_id);
           encode_family(rbml_w, 'd');
           encode_name(rbml_w, item.name);
           encode_unsafety(rbml_w, unsafety);
@@ -1209,9 +1215,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         let impl_items = tcx.impl_items.borrow();
         let items = impl_items.get(&def_id).unwrap();
 
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 'i');
         encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
         encode_name(rbml_w, item.name);
@@ -1272,10 +1278,7 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
                 None
             };
 
-            index.push(IndexEntry {
-                node: trait_item_def_id.def_id().xxx_node,
-                pos: rbml_w.mark_stable_position(),
-            });
+            index.record(trait_item_def_id.def_id(), rbml_w);
 
             match tcx.impl_or_trait_item(trait_item_def_id.def_id()) {
                 ty::ConstTraitItem(ref associated_const) => {
@@ -1307,9 +1310,9 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         }
       }
       hir::ItemTrait(_, _, _, ref ms) => {
-        add_to_index(item, rbml_w, index);
+        index.record(def_id, rbml_w);
         rbml_w.start_tag(tag_items_data_item);
-        encode_def_id(rbml_w, def_id);
+        encode_def_id_and_key(ecx, rbml_w, def_id);
         encode_family(rbml_w, 'I');
         encode_item_variances(rbml_w, ecx, item.id);
         let trait_def = tcx.lookup_trait_def(def_id);
@@ -1363,10 +1366,7 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
         for (i, &item_def_id) in r.iter().enumerate() {
             assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE);
 
-            index.push(IndexEntry {
-                node: item_def_id.def_id().xxx_node,
-                pos: rbml_w.mark_stable_position(),
-            });
+            index.record(item_def_id.def_id(), rbml_w);
 
             rbml_w.start_tag(tag_items_data_item);
 
@@ -1381,7 +1381,7 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
             match trait_item_type {
                 ty::ConstTraitItem(associated_const) => {
                     encode_name(rbml_w, associated_const.name);
-                    encode_def_id(rbml_w, associated_const.def_id);
+                    encode_def_id_and_key(ecx, rbml_w, associated_const.def_id);
                     encode_visibility(rbml_w, associated_const.vis);
 
                     let elem = ast_map::PathName(associated_const.name);
@@ -1422,7 +1422,7 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
                 }
                 ty::TypeTraitItem(associated_type) => {
                     encode_name(rbml_w, associated_type.name);
-                    encode_def_id(rbml_w, associated_type.def_id);
+                    encode_def_id_and_key(ecx, rbml_w, associated_type.def_id);
 
                     let elem = ast_map::PathName(associated_type.name);
                     encode_path(rbml_w,
@@ -1491,16 +1491,15 @@ fn add_to_index(item: &hir::Item, rbml_w: &mut Encoder,
 fn encode_info_for_foreign_item(ecx: &EncodeContext,
                                 rbml_w: &mut Encoder,
                                 nitem: &hir::ForeignItem,
-                                index: &mut Vec<IndexEntry>,
+                                index: &mut IndexData,
                                 path: PathElems,
                                 abi: abi::Abi) {
-    index.push(IndexEntry {
-        node: nitem.id,
-        pos: rbml_w.mark_stable_position(),
-    });
+    let def_id = ecx.tcx.map.local_def_id(nitem.id);
+
+    index.record(def_id, rbml_w);
 
     rbml_w.start_tag(tag_items_data_item);
-    encode_def_id(rbml_w, ecx.tcx.map.local_def_id(nitem.id));
+    encode_def_id_and_key(ecx, rbml_w, def_id);
     encode_visibility(rbml_w, nitem.vis);
     match nitem.node {
       hir::ForeignItemFn(ref fndecl, _) => {
@@ -1534,12 +1533,39 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
     rbml_w.end_tag();
 }
 
-fn my_visit_expr(_e: &hir::Expr) { }
+fn my_visit_expr(expr: &hir::Expr,
+                 rbml_w: &mut Encoder,
+                 ecx: &EncodeContext,
+                 index: &mut IndexData) {
+    match expr.node {
+        hir::ExprClosure(..) => {
+            let def_id = ecx.tcx.map.local_def_id(expr.id);
+
+            index.record(def_id, rbml_w);
+
+            rbml_w.start_tag(tag_items_data_item);
+            encode_def_id_and_key(ecx, rbml_w, def_id);
+
+            rbml_w.start_tag(tag_items_closure_ty);
+            write_closure_type(ecx, rbml_w, &ecx.tcx.tables.borrow().closure_tys[&def_id]);
+            rbml_w.end_tag();
+
+            rbml_w.start_tag(tag_items_closure_kind);
+            ecx.tcx.closure_kind(def_id).encode(rbml_w).unwrap();
+            rbml_w.end_tag();
+
+            ecx.tcx.map.with_path(expr.id, |path| encode_path(rbml_w, path));
+
+            rbml_w.end_tag();
+        }
+        _ => { }
+    }
+}
 
 fn my_visit_item(i: &hir::Item,
                  rbml_w: &mut Encoder,
                  ecx: &EncodeContext,
-                 index: &mut Vec<IndexEntry>) {
+                 index: &mut IndexData) {
     ecx.tcx.map.with_path(i.id, |path| {
         encode_info_for_item(ecx, rbml_w, i, index, path, i.vis);
     });
@@ -1548,7 +1574,7 @@ fn my_visit_item(i: &hir::Item,
 fn my_visit_foreign_item(ni: &hir::ForeignItem,
                          rbml_w: &mut Encoder,
                          ecx: &EncodeContext,
-                         index: &mut Vec<IndexEntry>) {
+                         index: &mut IndexData) {
     debug!("writing foreign item {}::{}",
             ecx.tcx.map.path_to_string(ni.id),
             ni.name);
@@ -1564,40 +1590,32 @@ fn my_visit_foreign_item(ni: &hir::ForeignItem,
 struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
     rbml_w_for_visit_item: &'a mut Encoder<'b>,
     ecx: &'a EncodeContext<'c,'tcx>,
-    index: &'a mut Vec<IndexEntry>,
+    index: &'a mut IndexData,
 }
 
 impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> {
     fn visit_expr(&mut self, ex: &hir::Expr) {
         visit::walk_expr(self, ex);
-        my_visit_expr(ex);
+        my_visit_expr(ex, self.rbml_w_for_visit_item, self.ecx, self.index);
     }
     fn visit_item(&mut self, i: &hir::Item) {
         visit::walk_item(self, i);
-        my_visit_item(i,
-                      self.rbml_w_for_visit_item,
-                      self.ecx,
-                      self.index);
+        my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index);
     }
     fn visit_foreign_item(&mut self, ni: &hir::ForeignItem) {
         visit::walk_foreign_item(self, ni);
-        my_visit_foreign_item(ni,
-                              self.rbml_w_for_visit_item,
-                              self.ecx,
-                              self.index);
+        my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index);
     }
 }
 
 fn encode_info_for_items(ecx: &EncodeContext,
                          rbml_w: &mut Encoder,
                          krate: &hir::Crate)
-                         -> Vec<IndexEntry> {
-    let mut index = Vec::new();
+                         -> IndexData {
+    let mut index = IndexData::new(ecx.tcx.map.num_local_def_ids());
+
     rbml_w.start_tag(tag_items_data);
-    index.push(IndexEntry {
-        node: CRATE_NODE_ID,
-        pos: rbml_w.mark_stable_position(),
-    });
+    index.record_index(CRATE_DEF_INDEX, rbml_w);
     encode_info_for_mod(ecx,
                         rbml_w,
                         &krate.module,
@@ -1617,13 +1635,9 @@ fn encode_info_for_items(ecx: &EncodeContext,
     index
 }
 
-
-
-
-fn encode_index(rbml_w: &mut Encoder, index: Vec<IndexEntry>)
-{
+fn encode_index(rbml_w: &mut Encoder, index: IndexData) {
     rbml_w.start_tag(tag_index);
-    index::write_index(index, rbml_w.writer);
+    index.write_index(rbml_w.writer);
     rbml_w.end_tag();
 }
 
@@ -1737,12 +1751,12 @@ fn get_ordered_deps(cstore: &cstore::CStore)
 fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
     rbml_w.start_tag(tag_lang_items);
 
-    for (i, &def_id) in ecx.tcx.lang_items.items() {
-        if let Some(id) = def_id {
-            if let Some(id) = ecx.tcx.map.as_local_node_id(id) {
+    for (i, &opt_def_id) in ecx.tcx.lang_items.items() {
+        if let Some(def_id) = opt_def_id {
+            if def_id.is_local() {
                 rbml_w.start_tag(tag_lang_items_item);
                 rbml_w.wr_tagged_u32(tag_lang_items_item_id, i as u32);
-                rbml_w.wr_tagged_u32(tag_lang_items_item_node_id, id as u32);
+                rbml_w.wr_tagged_u32(tag_lang_items_item_index, def_id.index.as_u32());
                 rbml_w.end_tag();
             }
         }
@@ -1776,7 +1790,10 @@ fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) {
 
 fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) {
     match ecx.tcx.sess.plugin_registrar_fn.get() {
-        Some(id) => { rbml_w.wr_tagged_u32(tag_plugin_registrar_fn, id); }
+        Some(id) => {
+            let def_id = ecx.tcx.map.local_def_id(id);
+            rbml_w.wr_tagged_u32(tag_plugin_registrar_fn, def_id.index.as_u32());
+        }
         None => {}
     }
 }
@@ -1821,24 +1838,26 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
     rbml_w.end_tag();
 }
 
-fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &hir::Crate) {
-    struct StructFieldVisitor<'a, 'b:'a> {
-        rbml_w: &'a mut Encoder<'b>,
+fn encode_struct_field_attrs(ecx: &EncodeContext,
+                             rbml_w: &mut Encoder,
+                             krate: &hir::Crate) {
+    struct StructFieldVisitor<'a, 'b:'a, 'c:'a, 'tcx:'b> {
+        ecx: &'a EncodeContext<'b, 'tcx>,
+        rbml_w: &'a mut Encoder<'c>,
     }
 
-    impl<'a, 'b, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b> {
+    impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b, 'c, 'tcx> {
         fn visit_struct_field(&mut self, field: &hir::StructField) {
             self.rbml_w.start_tag(tag_struct_field);
-            self.rbml_w.wr_tagged_u32(tag_struct_field_id, field.node.id);
+            let def_id = self.ecx.tcx.map.local_def_id(field.node.id);
+            encode_def_id(self.rbml_w, def_id);
             encode_attributes(self.rbml_w, &field.node.attrs);
             self.rbml_w.end_tag();
         }
     }
 
     rbml_w.start_tag(tag_struct_fields);
-    visit::walk_crate(&mut StructFieldVisitor {
-        rbml_w: rbml_w
-    }, krate);
+    visit::walk_crate(&mut StructFieldVisitor { ecx: ecx, rbml_w: rbml_w }, krate);
     rbml_w.end_tag();
 }
 
@@ -1925,8 +1944,9 @@ fn encode_misc_info(ecx: &EncodeContext,
 // definition (as that's not defined in this crate).
 fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) {
     rbml_w.start_tag(tag_reachable_ids);
-    for id in ecx.reachable {
-        rbml_w.wr_tagged_u32(tag_reachable_id, *id);
+    for &id in ecx.reachable {
+        let def_id = ecx.tcx.map.local_def_id(id);
+        rbml_w.wr_tagged_u32(tag_reachable_id, def_id.index.as_u32());
     }
     rbml_w.end_tag();
 }
@@ -2139,7 +2159,7 @@ struct Stats {
     encode_index(&mut rbml_w, items_index);
     stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i;
 
-    encode_struct_field_attrs(&mut rbml_w, krate);
+    encode_struct_field_attrs(&ecx, &mut rbml_w, krate);
 
     stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();
 
index b02a9022a7a6e835f37f24592cb8ab24a34afce9..c60b789a2f1bfea2120605c9c662ad183e5305cd 100644 (file)
 // option. This file may not be copied, modified, or distributed
 // except according to those terms.
 
+use middle::def_id::{DefId, DefIndex};
+use rbml;
+use rbml::writer::Encoder;
 use std::io::{Cursor, Write};
 use std::slice;
 use std::u32;
-use syntax::ast::NodeId;
 
-#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)]
-pub struct IndexEntry {
-    pub node: NodeId,
-    pub pos: u64
-}
-
-#[derive(Debug)]
-pub struct IndexArrayEntry {
-    bits: u32,
-    first_pos: u32
+/// As part of the metadata, we generate an index that stores, for
+/// each DefIndex, the position of the corresponding RBML document (if
+/// any).  This is just a big `[u32]` slice, where an entry of
+/// `u32::MAX` indicates that there is no RBML document. This little
+/// struct just stores the offsets within the metadata of the start
+/// and end of this slice. These are actually part of an RBML
+/// document, but for looking things up in the metadata, we just
+/// discard the RBML positioning and jump directly to the data.
+pub struct Index {
+    data_start: usize,
+    data_end: usize,
 }
 
-impl IndexArrayEntry {
-    fn encode_to<W: Write>(&self, b: &mut W) {
-        write_be_u32(b, self.bits);
-        write_be_u32(b, self.first_pos);
+impl Index {
+    /// Given the RBML doc representing the index, save the offests
+    /// for later.
+    pub fn from_rbml(index: rbml::Doc) -> Index {
+        Index { data_start: index.start, data_end: index.end }
     }
 
-    fn decode_from(b: &[u32]) -> Self {
-        IndexArrayEntry {
-            bits: b[0].to_be(),
-            first_pos: b[1].to_be()
+    /// Given the metadata, extract out the offset of a particular
+    /// DefIndex (if any).
+    #[inline(never)]
+    pub fn lookup_item(&self, bytes: &[u8], def_index: DefIndex) -> Option<u32> {
+        let words = bytes_to_words(&bytes[self.data_start..self.data_end]);
+        let index = def_index.as_usize();
+
+        debug!("lookup_item: index={:?} words.len={:?}",
+               index, words.len());
+
+        let position = u32::from_be(words[index]);
+        if position == u32::MAX {
+            debug!("lookup_item: position=u32::MAX");
+            None
+        } else {
+            debug!("lookup_item: position={:?}", position);
+            Some(position)
         }
     }
 }
 
-/// The Item Index
-///
-/// This index maps the NodeId of each item to its location in the
-/// metadata.
-///
-/// The index is a sparse bit-vector consisting of a index-array
-/// and a position-array. Each entry in the index-array handles 32 nodes.
-/// The first word is a bit-array consisting of the nodes that hold items,
-/// the second is the index of the first of the items in the position-array.
-/// If there is a large set of non-item trailing nodes, they can be omitted
-/// from the index-array.
-///
-/// The index is serialized as an array of big-endian 32-bit words.
-/// The first word is the number of items in the position-array.
-/// Then, for each item, its position in the metadata follows.
-/// After that the index-array is stored.
-///
-/// struct index {
-///     u32 item_count;
-///     u32 items[self.item_count];
-///     struct { u32 bits; u32 offset; } positions[..];
-/// }
-pub struct Index {
-    position_start: usize,
-    index_start: usize,
-    index_end: usize,
+/// While we are generating the metadata, we also track the position
+/// of each DefIndex. It is not required that all definitions appear
+/// in the metadata, nor that they are serialized in order, and
+/// therefore we first allocate the vector here and fill it with
+/// `u32::MAX`. Whenever an index is visited, we fill in the
+/// appropriate spot by calling `record_position`. We should never
+/// visit the same index twice.
+pub struct IndexData {
+    positions: Vec<u32>,
 }
 
-pub fn write_index(mut entries: Vec<IndexEntry>, buf: &mut Cursor<Vec<u8>>) {
-    assert!(entries.len() < u32::MAX as usize);
-    entries.sort();
-
-    let mut last_entry = IndexArrayEntry { bits: 0, first_pos: 0 };
-
-    write_be_u32(buf, entries.len() as u32);
-    for &IndexEntry { pos, .. } in &entries {
-        assert!(pos < u32::MAX as u64);
-        write_be_u32(buf, pos as u32);
+impl IndexData {
+    pub fn new(max_index: usize) -> IndexData {
+        IndexData {
+            positions: vec![u32::MAX; max_index]
+        }
     }
 
-    let mut pos_in_index_array = 0;
-    for (i, &IndexEntry { node, .. }) in entries.iter().enumerate() {
-        let (x, s) = (node / 32 as u32, node % 32 as u32);
-        while x > pos_in_index_array {
-            pos_in_index_array += 1;
-            last_entry.encode_to(buf);
-            last_entry = IndexArrayEntry { bits: 0, first_pos: i as u32 };
-        }
-        last_entry.bits |= 1<<s;
+    pub fn record(&mut self, def_id: DefId, encoder: &mut Encoder) {
+        assert!(def_id.is_local());
+        self.record_index(def_id.index, encoder)
     }
-    last_entry.encode_to(buf);
 
-    info!("write_index: {} items, {} array entries",
-          entries.len(), pos_in_index_array);
-}
+    pub fn record_index(&mut self, item: DefIndex, encoder: &mut Encoder) {
+        let item = item.as_usize();
 
-impl Index {
-    fn lookup_index(&self, index: &[u32], i: u32) -> Option<IndexArrayEntry> {
-        let ix = (i as usize)*2;
-        if ix >= index.len() {
-            None
-        } else {
-            Some(IndexArrayEntry::decode_from(&index[ix..ix+2]))
-        }
-    }
+        let position = encoder.mark_stable_position();
 
-    fn item_from_pos(&self, positions: &[u32], pos: u32) -> u32 {
-        positions[pos as usize].to_be()
-    }
+        assert!(position < (u32::MAX as u64));
+        let position = position as u32;
 
-    #[inline(never)]
-    pub fn lookup_item(&self, buf: &[u8], node: NodeId) -> Option<u32> {
-        let index = bytes_to_words(&buf[self.index_start..self.index_end]);
-        let positions = bytes_to_words(&buf[self.position_start..self.index_start]);
-        let (x, s) = (node / 32 as u32, node % 32 as u32);
-        let result = match self.lookup_index(index, x) {
-            Some(IndexArrayEntry { bits, first_pos }) => {
-                let bit = 1<<s;
-                if bits & bit == 0 {
-                    None
-                } else {
-                    let prev_nodes_for_entry = (bits&(bit-1)).count_ones();
-                    Some(self.item_from_pos(
-                        positions,
-                        first_pos+prev_nodes_for_entry))
-                }
-            }
-            None => None // trailing zero
-        };
-        debug!("lookup_item({:?}) = {:?}", node, result);
-        result
+        assert!(self.positions[item] == u32::MAX,
+                "recorded position for item {:?} twice, first at {:?} and now at {:?}",
+                item, self.positions[item], position);
+
+        self.positions[item] = position;
     }
 
-    pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self {
-        let buf = bytes_to_words(&buf[start..end]);
-        let position_count = buf[0].to_be() as usize;
-        let position_len = position_count*4;
-        info!("loaded index - position: {}-{}-{}", start, start+position_len, end);
-        debug!("index contents are {:?}",
-               buf.iter().map(|b| format!("{:08x}", b)).collect::<Vec<_>>().concat());
-        assert!(end-4-start >= position_len);
-        assert_eq!((end-4-start-position_len)%8, 0);
-        Index {
-            position_start: start+4,
-            index_start: start+position_len+4,
-            index_end: end
+    pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) {
+        for &position in &self.positions {
+            write_be_u32(buf, position);
         }
     }
 }
@@ -162,47 +114,3 @@ fn bytes_to_words(b: &[u8]) -> &[u32] {
     assert!(b.len() % 4 == 0);
     unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len()/4) }
 }
-
-#[test]
-fn test_index() {
-    let entries = vec![
-        IndexEntry { node: 0, pos: 17 },
-        IndexEntry { node: 31, pos: 29 },
-        IndexEntry { node: 32, pos: 1175 },
-        IndexEntry { node: 191, pos: 21 },
-        IndexEntry { node: 128, pos: 34 },
-        IndexEntry { node: 145, pos: 70 },
-        IndexEntry { node: 305, pos: 93214 },
-        IndexEntry { node: 138, pos: 64 },
-        IndexEntry { node: 129, pos: 53 },
-        IndexEntry { node: 192, pos: 33334 },
-        IndexEntry { node: 200, pos: 80123 },
-    ];
-    let mut c = Cursor::new(vec![]);
-    write_index(entries.clone(), &mut c);
-    let mut buf = c.into_inner();
-    let expected: &[u8] = &[
-        0, 0, 0, 11, // # entries
-        // values:
-        0,0,0,17, 0,0,0,29, 0,0,4,151, 0,0,0,34,
-        0,0,0,53, 0,0,0,64, 0,0,0,70, 0,0,0,21,
-        0,0,130,54, 0,1,56,251, 0,1,108,30,
-        // index:
-        128,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,2,
-        0,0,0,0,0,0,0,3,   0,0,0,0,0,0,0,3,
-        0,2,4,3,0,0,0,3,   128,0,0,0,0,0,0,7,
-        0,0,1,1,0,0,0,8,   0,0,0,0,0,0,0,10,
-        0,0,0,0,0,0,0,10,  0,2,0,0,0,0,0,10
-    ];
-    assert_eq!(buf, expected);
-
-    // insert some junk padding
-    for i in 0..17 { buf.insert(0, i); buf.push(i) }
-    let index = Index::from_buf(&buf, 17, buf.len()-17);
-
-    // test round-trip
-    for i in 0..4096 {
-        assert_eq!(index.lookup_item(&buf, i),
-                   entries.iter().find(|e| e.node == i).map(|n| n.pos as u32));
-    }
-}
index f023049d78f61bfcd4794259162de85b507d97af..4657323c1726d0998d6fc7ab5968582606080a42 100644 (file)
 
 #![allow(non_camel_case_types)]
 
-pub use self::DefIdSource::*;
-
 use rustc_front::hir;
 
-use middle::def_id::DefId;
+use middle::def_id::{DefId, DefIndex};
 use middle::region;
 use middle::subst;
 use middle::subst::VecPerParamSpace;
 // parse_from_str. Extra parameters are for converting to/from def_ids in the
 // data buffer. Whatever format you choose should not contain pipe characters.
 
-// Def id conversion: when we encounter def-ids, they have to be translated.
-// For example, the crate number must be converted from the crate number used
-// in the library we are reading from into the local crate numbers in use
-// here.  To perform this translation, the type decoder is supplied with a
-// conversion function of type `conv_did`.
-//
-// Sometimes, particularly when inlining, the correct translation of the
-// def-id will depend on where it originated from.  Therefore, the conversion
-// function is given an indicator of the source of the def-id.  See
-// astencode.rs for more information.
-#[derive(Copy, Clone, Debug)]
-pub enum DefIdSource {
-    // Identifies a struct, trait, enum, etc.
-    NominalType,
-
-    // Identifies a type alias (`type X = ...`).
-    TypeWithId,
-
-    // Identifies a region parameter (`fn foo<'X>() { ... }`).
-    RegionParameter,
-
-    // Identifies a closure
-    ClosureSource
-}
-
-pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, DefId) -> DefId;
+pub type DefIdConvert<'a> = &'a mut FnMut(DefId) -> DefId;
 
 pub struct TyDecoder<'a, 'tcx: 'a> {
     data: &'a [u8],
@@ -183,7 +156,7 @@ fn parse_bound_region(&mut self) -> ty::BoundRegion {
                 ty::BrAnon(id)
             }
             '[' => {
-                let def = self.parse_def(RegionParameter);
+                let def = self.parse_def();
                 let name = token::intern(&self.parse_str(']'));
                 ty::BrNamed(def, name)
             }
@@ -209,7 +182,7 @@ pub fn parse_region(&mut self) -> ty::Region {
             }
             'B' => {
                 assert_eq!(self.next(), '[');
-                let def_id = self.parse_def(NominalType);
+                let def_id = self.parse_def();
                 let space = self.parse_param_space();
                 assert_eq!(self.next(), '|');
                 let index = self.parse_u32();
@@ -309,7 +282,7 @@ fn parse_str(&mut self, term: char) -> String {
     }
 
     pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> {
-        let def = self.parse_def(NominalType);
+        let def = self.parse_def();
         let substs = self.tcx.mk_substs(self.parse_substs());
         ty::TraitRef {def_id: def, substs: substs}
     }
@@ -338,7 +311,7 @@ pub fn parse_ty(&mut self) -> Ty<'tcx> {
             'c' => return tcx.types.char,
             't' => {
                 assert_eq!(self.next(), '[');
-                let did = self.parse_def(NominalType);
+                let did = self.parse_def();
                 let substs = self.parse_substs();
                 assert_eq!(self.next(), ']');
                 let def = self.tcx.lookup_adt_def(did);
@@ -385,7 +358,7 @@ pub fn parse_ty(&mut self) -> Ty<'tcx> {
                 return tcx.mk_tup(params);
             }
             'F' => {
-                let def_id = self.parse_def(NominalType);
+                let def_id = self.parse_def();
                 return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty()));
             }
             'G' => {
@@ -427,13 +400,13 @@ pub fn parse_ty(&mut self) -> Ty<'tcx> {
                 return tt;
             }
             '\"' => {
-                let _ = self.parse_def(TypeWithId);
+                let _ = self.parse_def();
                 let inner = self.parse_ty();
                 inner
             }
             'a' => {
                 assert_eq!(self.next(), '[');
-                let did = self.parse_def(NominalType);
+                let did = self.parse_def();
                 let substs = self.parse_substs();
                 assert_eq!(self.next(), ']');
                 let def = self.tcx.lookup_adt_def(did);
@@ -441,7 +414,7 @@ pub fn parse_ty(&mut self) -> Ty<'tcx> {
             }
             'k' => {
                 assert_eq!(self.next(), '[');
-                let did = self.parse_def(ClosureSource);
+                let did = self.parse_def();
                 let substs = self.parse_substs();
                 let mut tys = vec![];
                 while self.peek() != '.' {
@@ -476,9 +449,9 @@ fn parse_mt(&mut self) -> ty::TypeAndMut<'tcx> {
         ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
     }
 
-    fn parse_def(&mut self, source: DefIdSource) -> DefId {
+    fn parse_def(&mut self) -> DefId {
         let def_id = parse_defid(self.scan(|c| c == '|'));
-        return (self.conv_def_id)(source, def_id);
+        return (self.conv_def_id)(def_id);
     }
 
     fn parse_uint(&mut self) -> usize {
@@ -581,7 +554,7 @@ pub fn parse_predicate(&mut self) -> ty::Predicate<'tcx> {
             'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
             'w' => ty::Predicate::WellFormed(self.parse_ty()),
             'O' => {
-                let def_id = self.parse_def(NominalType);
+                let def_id = self.parse_def();
                 assert_eq!(self.next(), '|');
                 ty::Predicate::ObjectSafe(def_id)
             }
@@ -601,12 +574,12 @@ fn parse_projection_predicate(&mut self) -> ty::ProjectionPredicate<'tcx> {
 
     pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
         let name = self.parse_name(':');
-        let def_id = self.parse_def(NominalType);
+        let def_id = self.parse_def();
         let space = self.parse_param_space();
         assert_eq!(self.next(), '|');
         let index = self.parse_u32();
         assert_eq!(self.next(), '|');
-        let default_def_id = self.parse_def(NominalType);
+        let default_def_id = self.parse_def();
         let default = self.parse_opt(|this| this.parse_ty());
         let object_lifetime_default = self.parse_object_lifetime_default();
 
@@ -623,7 +596,7 @@ pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
 
     pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
         let name = self.parse_name(':');
-        let def_id = self.parse_def(NominalType);
+        let def_id = self.parse_def();
         let space = self.parse_param_space();
         assert_eq!(self.next(), '|');
         let index = self.parse_u32();
@@ -731,11 +704,12 @@ fn parse_defid(buf: &[u8]) -> DefId {
     let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
         s.parse::<usize>().ok()
     }) {
-        Some(dn) => dn as ast::NodeId,
+        Some(dn) => dn,
         None => panic!("internal error: parse_defid: id expected, found {:?}",
                        def_part)
     };
-    DefId { krate: crate_num, xxx_node: def_num }
+    let index = DefIndex::new(def_num);
+    DefId { krate: crate_num, index: index }
 }
 
 fn parse_unsafety(c: char) -> hir::Unsafety {
index 02bd9951d341a3e0427f7b425e54f54de0921108..672ae5d3fb69c030f555e8626750bb76fcf85623 100644 (file)
 
 use metadata::common as c;
 use metadata::cstore as cstore;
-use metadata::cstore::LOCAL_CRATE;
 use session::Session;
 use metadata::decoder;
 use metadata::encoder as e;
 use metadata::inline::{InlinedItem, InlinedItemRef};
 use metadata::tydecode;
-use metadata::tydecode::{DefIdSource, NominalType, TypeWithId};
-use metadata::tydecode::{RegionParameter, ClosureSource};
 use metadata::tyencode;
 use middle::ty::adjustment;
 use middle::ty::cast;
@@ -73,10 +70,6 @@ trait tr {
     fn tr(&self, dcx: &DecodeContext) -> Self;
 }
 
-trait tr_intern {
-    fn tr_intern(&self, dcx: &DecodeContext) -> DefId;
-}
-
 // ______________________________________________________________________
 // Top-level methods.
 
@@ -130,10 +123,12 @@ fn new_span(&self, span: Span) -> Span {
 pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
                                  tcx: &ty::ctxt<'tcx>,
                                  path: Vec<ast_map::PathElem>,
+                                 def_path: ast_map::DefPath,
                                  par_doc: rbml::Doc)
-                                 -> Result<&'tcx InlinedItem, Vec<ast_map::PathElem>> {
+                                 -> Result<&'tcx InlinedItem, (Vec<ast_map::PathElem>,
+                                                               ast_map::DefPath)> {
     match par_doc.opt_child(c::tag_ast) {
-      None => Err(path),
+      None => Err((path, def_path)),
       Some(ast_doc) => {
         let mut path_as_str = None;
         debug!("> Decoding inlined fn: {:?}::?",
@@ -154,7 +149,7 @@ 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, raw_ii, dcx);
+        let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, def_path, raw_ii, dcx);
 
         let name = match *ii {
             InlinedItem::Item(ref i) => i.name,
@@ -214,24 +209,10 @@ pub fn tr_id(&self, id: ast::NodeId) -> ast::NodeId {
     /// be inlined.  Note that even when the inlined function is referencing itself recursively, we
     /// would want `tr_def_id` for that reference--- conceptually the function calls the original,
     /// non-inlined version, and trans deals with linking that recursive call to the inlined copy.
-    ///
-    /// However, there are a *few* cases where def-ids are used but we know that the thing being
-    /// referenced is in fact *internal* to the item being inlined.  In those cases, you should use
-    /// `tr_intern_def_id()` below.
     pub fn tr_def_id(&self, did: DefId) -> DefId {
-
         decoder::translate_def_id(self.cdata, did)
     }
 
-    /// Translates an INTERNAL def-id, meaning a def-id that is
-    /// known to refer to some part of the item currently being
-    /// inlined.  In that case, we want to convert the def-id to
-    /// refer to the current crate and to the new, inlined node-id.
-    pub fn tr_intern_def_id(&self, did: DefId) -> DefId {
-        assert_eq!(did.krate, LOCAL_CRATE);
-        DefId { krate: LOCAL_CRATE, xxx_node: self.tr_id(did.xxx_node) }
-    }
-
     /// Translates a `Span` from an extern crate to the corresponding `Span`
     /// within the local crate's codemap. `creader::import_codemap()` will
     /// already have allocated any additionally needed FileMaps in the local
@@ -290,12 +271,6 @@ pub fn tr_span(&self, span: Span) -> Span {
     }
 }
 
-impl tr_intern for DefId {
-    fn tr_intern(&self, dcx: &DecodeContext) -> DefId {
-        dcx.tr_intern_def_id(*self)
-    }
-}
-
 impl tr for DefId {
     fn tr(&self, dcx: &DecodeContext) -> DefId {
         dcx.tr_def_id(*self)
@@ -575,10 +550,6 @@ fn read_method_callee<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
     }
 }
 
-pub fn encode_closure_kind(ebml_w: &mut Encoder, kind: ty::ClosureKind) {
-    kind.encode(ebml_w).unwrap();
-}
-
 pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) {
     kind.encode(ebml_w).unwrap();
 }
@@ -632,8 +603,6 @@ fn ty_str_ctxt<'b>(&'b self) -> tyencode::ctxt<'b, 'tcx> {
 }
 
 trait rbml_writer_helpers<'tcx> {
-    fn emit_closure_type<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
-                             closure_type: &ty::ClosureTy<'tcx>);
     fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region);
     fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
     fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
@@ -662,14 +631,6 @@ fn emit_auto_deref_ref<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
 }
 
 impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
-    fn emit_closure_type<'b>(&mut self,
-                             ecx: &e::EncodeContext<'b, 'tcx>,
-                             closure_type: &ty::ClosureTy<'tcx>) {
-        self.emit_opaque(|this| {
-            Ok(e::write_closure_type(ecx, this, closure_type))
-        });
-    }
-
     fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region) {
         self.emit_opaque(|this| Ok(e::write_region(ecx, this, r)));
     }
@@ -1005,24 +966,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
         })
     }
 
-    if let Some(def_id) = opt_def_id {
-        if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&def_id) {
-            rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
-                rbml_w.id(id);
-                rbml_w.emit_closure_type(ecx, closure_type);
-            })
-        }
-    }
-
-    if let Some(def_id) = opt_def_id {
-        if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&def_id) {
-            rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
-                rbml_w.id(id);
-                encode_closure_kind(rbml_w, *closure_kind)
-            })
-        }
-    }
-
     if let Some(cast_kind) = tcx.cast_kinds.borrow().get(&id) {
         rbml_w.tag(c::tag_table_cast_kinds, |rbml_w| {
             rbml_w.id(id);
@@ -1080,17 +1023,12 @@ fn read_auto_adjustment<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                     -> adjustment::AutoAdjustment<'tcx>;
     fn read_cast_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                  -> cast::CastKind;
-    fn read_closure_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-                                 -> ty::ClosureKind;
-    fn read_closure_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-                               -> ty::ClosureTy<'tcx>;
     fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                                    -> adjustment::AutoDerefRef<'tcx>;
     fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
                             -> adjustment::AutoRef<'tcx>;
     fn convert_def_id(&mut self,
                       dcx: &DecodeContext,
-                      source: DefIdSource,
                       did: DefId)
                       -> DefId;
 
@@ -1114,7 +1052,7 @@ fn read_ty_nodcx(&mut self,
         self.read_opaque(|_, doc| {
             Ok(
                 tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc,
-                                              &mut |_, id| decoder::translate_def_id(cdata, id))
+                                              &mut |id| decoder::translate_def_id(cdata, id))
                     .parse_ty())
         }).unwrap()
     }
@@ -1136,7 +1074,7 @@ fn read_substs_nodcx(&mut self,
         self.read_opaque(|_, doc| {
             Ok(
                 tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc,
-                                              &mut |_, id| decoder::translate_def_id(cdata, id))
+                                              &mut |id| decoder::translate_def_id(cdata, id))
                     .parse_substs())
         }).unwrap()
     }
@@ -1149,7 +1087,7 @@ fn read_ty_encoded<'b, 'c, F, R>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>, o
             Ok(op(
                 &mut tydecode::TyDecoder::with_doc(
                     dcx.tcx, dcx.cdata.cnum, doc,
-                    &mut |s, a| this.convert_def_id(dcx, s, a))))
+                    &mut |a| this.convert_def_id(dcx, a))))
         }).unwrap();
 
         fn type_string(doc: rbml::Doc) -> String {
@@ -1238,7 +1176,7 @@ fn read_substs<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
                            -> subst::Substs<'tcx> {
         self.read_opaque(|this, doc| {
             Ok(tydecode::TyDecoder::with_doc(dcx.tcx, dcx.cdata.cnum, doc,
-                                             &mut |s, a| this.convert_def_id(dcx, s, a))
+                                             &mut |a| this.convert_def_id(dcx, a))
                .parse_substs())
         }).unwrap()
     }
@@ -1345,18 +1283,6 @@ fn read_cast_kind<'b, 'c>(&mut self, _dcx: &DecodeContext<'b, 'c, 'tcx>)
         Decodable::decode(self).unwrap()
     }
 
-    fn read_closure_kind<'b, 'c>(&mut self, _dcx: &DecodeContext<'b, 'c, 'tcx>)
-                                 -> ty::ClosureKind
-    {
-        Decodable::decode(self).unwrap()
-    }
-
-    fn read_closure_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-                               -> ty::ClosureTy<'tcx>
-    {
-        self.read_ty_encoded(dcx, |decoder| decoder.parse_closure_ty())
-    }
-
     /// Converts a def-id that appears in a type.  The correct
     /// translation will depend on what kind of def-id this is.
     /// This is a subtle point: type definitions are not
@@ -1391,14 +1317,10 @@ fn read_closure_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
     /// def-ids so that all these distinctions were unnecessary.
     fn convert_def_id(&mut self,
                       dcx: &DecodeContext,
-                      source: tydecode::DefIdSource,
                       did: DefId)
                       -> DefId {
-        let r = match source {
-            NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
-            ClosureSource => dcx.tr_intern_def_id(did)
-        };
-        debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
+        let r = dcx.tr_def_id(did);
+        debug!("convert_def_id(did={:?})={:?}", did, r);
         return r;
     }
 }
@@ -1485,20 +1407,6 @@ fn decode_side_tables(dcx: &DecodeContext,
                             val_dsr.read_auto_adjustment(dcx);
                         dcx.tcx.tables.borrow_mut().adjustments.insert(id, adj);
                     }
-                    c::tag_table_closure_tys => {
-                        let closure_ty =
-                            val_dsr.read_closure_ty(dcx);
-                        dcx.tcx.tables.borrow_mut().closure_tys.insert(
-                            dcx.tcx.map.local_def_id(id),
-                            closure_ty);
-                    }
-                    c::tag_table_closure_kinds => {
-                        let closure_kind =
-                            val_dsr.read_closure_kind(dcx);
-                        dcx.tcx.tables.borrow_mut().closure_kinds.insert(
-                            dcx.tcx.map.local_def_id(id),
-                            closure_kind);
-                    }
                     c::tag_table_cast_kinds => {
                         let cast_kind =
                             val_dsr.read_cast_kind(dcx);
index 00cfbf2dfe2c23a3de222fb2eff75addeb6c9f4f..91d9f70aee9a7873c4f08d26c6df87e1413cf637 100644 (file)
@@ -92,7 +92,7 @@ fn variant_expr<'a>(variants: &'a [P<hir::Variant>], id: ast::NodeId)
         let expr_id = match
             csearch::maybe_get_item_ast(
                 tcx, enum_def,
-                Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d)))
+                Box::new(|a, b, c, d, e| astencode::decode_inlined_item(a, b, c, d, e)))
         {
             csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
                 hir::ItemEnum(hir::EnumDef { .. }, _) => {
@@ -168,7 +168,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
         }
         let mut used_ref_id = false;
         let expr_id = match csearch::maybe_get_item_ast(tcx, def_id,
-            Box::new(|a, b, c, d| astencode::decode_inlined_item(a, b, c, d))) {
+            Box::new(|a, b, c, d, e| astencode::decode_inlined_item(a, b, c, d, e))) {
             csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
                 hir::ItemConst(_, ref const_expr) => Some(const_expr.id),
                 _ => None
@@ -224,7 +224,7 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: DefId)
     }
 
     let fn_id = match csearch::maybe_get_item_ast(tcx, def_id,
-        box |a, b, c, d| astencode::decode_inlined_item(a, b, c, d)) {
+        box |a, b, c, d, e| astencode::decode_inlined_item(a, b, c, d, e)) {
         csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => Some(item.id),
         csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id),
         _ => None
index f8f3412c8bb2c24f84fa9eb9e10b104703b0de70..ed7a1d75a52e929fafb929de196f9ef53dafe667 100644 (file)
 
 use metadata::cstore::LOCAL_CRATE;
 use middle::ty;
-use syntax::ast::{CrateNum, NodeId};
+use syntax::ast::CrateNum;
 use std::fmt;
+use std::u32;
 
+/// A DefIndex is an index into the hir-map for a crate, identifying a
+/// particular definition. It should really be considered an interned
+/// shorthand for a particular DefPath.
+#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
+           RustcDecodable, Hash, Copy)]
+pub struct DefIndex(u32);
+
+impl DefIndex {
+    pub fn new(x: usize) -> DefIndex {
+        assert!(x < (u32::MAX as usize));
+        DefIndex(x as u32)
+    }
+
+    pub fn from_u32(x: u32) -> DefIndex {
+        DefIndex(x)
+    }
+
+    pub fn as_usize(&self) -> usize {
+        self.0 as usize
+    }
+
+    pub fn as_u32(&self) -> u32 {
+        self.0
+    }
+}
+
+/// The crate root is always assigned index 0 by the AST Map code,
+/// thanks to `NodeCollector::new`.
+pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
+
+/// A DefId identifies a particular *definition*, by combining a crate
+/// index and a def index.
 #[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
            RustcDecodable, Hash, Copy)]
 pub struct DefId {
     pub krate: CrateNum,
-    pub xxx_node: NodeId,
+    pub index: DefIndex,
 }
 
 impl fmt::Debug for DefId {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        try!(write!(f, "DefId {{ krate: {}, node: {}",
-                    self.krate, self.xxx_node));
+        try!(write!(f, "DefId {{ krate: {:?}, node: {:?}",
+                    self.krate, self.index));
 
         // Unfortunately, there seems to be no way to attempt to print
         // a path for a def-id, so I'll just make a best effort for now
@@ -41,8 +74,8 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 
 impl DefId {
-    pub fn xxx_local(id: NodeId) -> DefId {
-        DefId { krate: LOCAL_CRATE, xxx_node: id }
+    pub fn local(index: DefIndex) -> DefId {
+        DefId { krate: LOCAL_CRATE, index: index }
     }
 
     pub fn is_local(&self) -> bool {
index 512faa8f8b53465cdbc78411a8275ce3967cee93..1eed7fb95a1f580dc19e519ff7c2c5caf2738c33 100644 (file)
@@ -276,7 +276,7 @@ enum PassArgs {
 }
 
 impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
-    pub fn new(delegate: &'d mut Delegate<'tcx>,
+    pub fn new(delegate: &'d mut (Delegate<'tcx>),
                typer: &'t infer::InferCtxt<'a, 'tcx>)
                -> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a
     {
index 3def56f94a1818b62cc631f80782500b21e4a4ec..3b44dc12ac197412f0bd8e8c3af37c969952d178 100644 (file)
@@ -1455,7 +1455,15 @@ pub fn closure_kind(&self,
                         def_id: DefId)
                         -> Option<ty::ClosureKind>
     {
-        self.tables.borrow().closure_kinds.get(&def_id).cloned()
+        if def_id.is_local() {
+            self.tables.borrow().closure_kinds.get(&def_id).cloned()
+        } else {
+            // During typeck, ALL closures are local. But afterwards,
+            // during trans, we see closure ids from other traits.
+            // That may require loading the closure data out of the
+            // cstore.
+            Some(ty::Tables::closure_kind(&self.tables, self.tcx, def_id))
+        }
     }
 
     pub fn closure_type(&self,
@@ -1463,12 +1471,11 @@ pub fn closure_type(&self,
                         substs: &ty::ClosureSubsts<'tcx>)
                         -> ty::ClosureTy<'tcx>
     {
-        let closure_ty = self.tables
-                             .borrow()
-                             .closure_tys
-                             .get(&def_id)
-                             .unwrap()
-                             .subst(self.tcx, &substs.func_substs);
+        let closure_ty =
+            ty::Tables::closure_type(self.tables,
+                                     self.tcx,
+                                     def_id,
+                                     substs);
 
         if self.normalize {
             normalize_associated_type(&self.tcx, &closure_ty)
index 73313a5c257a6d86663919a55479885004303ac6..03c75fc6cc370e1b45bb94115022f7f837db97ad 100644 (file)
@@ -208,8 +208,8 @@ pub fn collect_local_language_items(&mut self, krate: &hir::Crate) {
     pub fn collect_external_language_items(&mut self) {
         let crate_store = &self.session.cstore;
         crate_store.iter_crate_data(|crate_number, _crate_metadata| {
-            each_lang_item(crate_store, crate_number, |node_id, item_index| {
-                let def_id = DefId { krate: crate_number, xxx_node: node_id };
+            each_lang_item(crate_store, crate_number, |index, item_index| {
+                let def_id = DefId { krate: crate_number, index: index };
                 self.collect_item(item_index, def_id, DUMMY_SP);
                 true
             });
index 73519b8f579d569757945a19b4baf7525a741c02..be227e620b8811b567e551d18a9fe6b9318e58ec 100644 (file)
@@ -15,7 +15,7 @@
 use lint;
 use metadata::cstore::LOCAL_CRATE;
 use middle::def;
-use middle::def_id::DefId;
+use middle::def_id::{CRATE_DEF_INDEX, DefId};
 use middle::ty;
 use middle::privacy::PublicItems;
 use metadata::csearch;
@@ -383,7 +383,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &hir::Item, warn_about_defns: bool,
                 Some(cnum) => cnum,
                 None => return,
             };
-            let id = DefId { krate: cnum, xxx_node: ast::CRATE_NODE_ID };
+            let id = DefId { krate: cnum, index: CRATE_DEF_INDEX };
             maybe_do_stability_check(tcx, id, item.span, cb);
         }
 
index 5e12e77435a129f3c2426c97b67a409a53f04fe7..60f6cffa346af696b1b594671e926a172252b74b 100644 (file)
@@ -37,7 +37,6 @@
 use super::object_safety;
 use super::util;
 
-use metadata::cstore::LOCAL_CRATE;
 use middle::def_id::DefId;
 use middle::infer;
 use middle::infer::{InferCtxt, TypeFreshener};
@@ -1720,7 +1719,7 @@ fn builtin_bound(&mut self,
             // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
             ty::TyTuple(ref tys) => ok_if(tys.clone()),
 
-            ty::TyClosure(def_id, ref substs) => {
+            ty::TyClosure(_, ref substs) => {
                 // FIXME -- This case is tricky. In the case of by-ref
                 // closures particularly, we need the results of
                 // inference to decide how to reflect the type of each
@@ -1730,7 +1729,6 @@ fn builtin_bound(&mut self,
                 // captures are by value. Really what we ought to do
                 // is reserve judgement and then intertwine this
                 // analysis with closure inference.
-                assert_eq!(def_id.krate, LOCAL_CRATE);
 
                 // Unboxed closures shouldn't be
                 // implicitly copyable
@@ -1864,7 +1862,7 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
                 tys.clone()
             }
 
-            ty::TyClosure(def_id, ref substs) => {
+            ty::TyClosure(_, ref substs) => {
                 // FIXME(#27086). We are invariant w/r/t our
                 // substs.func_substs, but we don't see them as
                 // constituent types; this seems RIGHT but also like
@@ -1873,7 +1871,6 @@ fn constituent_types_for_ty(&self, t: Ty<'tcx>) -> Vec<Ty<'tcx>> {
                 // OIBIT interact? That is, there is no way to say
                 // "make me invariant with respect to this TYPE, but
                 // do not act as though I can reach it"
-                assert_eq!(def_id.krate, LOCAL_CRATE);
                 substs.upvar_tys.clone()
             }
 
index 57f04af2ba9138103fc05397540fa3356e2a8f75..906ff5b2656e75ec8e15fc64758f31d1d27f03c1 100644 (file)
@@ -16,6 +16,7 @@
 use front::map as ast_map;
 use session::Session;
 use lint;
+use metadata::csearch;
 use middle;
 use middle::def::DefMap;
 use middle::def_id::DefId;
@@ -134,6 +135,40 @@ pub fn empty() -> Tables<'tcx> {
             closure_kinds: DefIdMap(),
         }
     }
+
+    pub fn closure_kind(this: &RefCell<Self>,
+                        tcx: &ty::ctxt<'tcx>,
+                        def_id: DefId)
+                        -> ty::ClosureKind {
+        // If this is a local def-id, it should be inserted into the
+        // tables by typeck; else, it will be retreived from
+        // the external crate metadata.
+        if let Some(&kind) = this.borrow().closure_kinds.get(&def_id) {
+            return kind;
+        }
+
+        let kind = csearch::closure_kind(tcx, def_id);
+        this.borrow_mut().closure_kinds.insert(def_id, kind);
+        kind
+    }
+
+    pub fn closure_type(this: &RefCell<Self>,
+                        tcx: &ty::ctxt<'tcx>,
+                        def_id: DefId,
+                        substs: &ClosureSubsts<'tcx>)
+                        -> ty::ClosureTy<'tcx>
+    {
+        // If this is a local def-id, it should be inserted into the
+        // tables by typeck; else, it will be retreived from
+        // the external crate metadata.
+        if let Some(ty) = this.borrow().closure_tys.get(&def_id) {
+            return ty.subst(tcx, &substs.func_substs);
+        }
+
+        let ty = csearch::closure_ty(tcx, def_id);
+        this.borrow_mut().closure_tys.insert(def_id, ty.clone());
+        ty.subst(tcx, &substs.func_substs)
+    }
 }
 
 impl<'tcx> CommonTypes<'tcx> {
@@ -336,19 +371,8 @@ pub struct ctxt<'tcx> {
     /// constitute it.
     pub fragment_infos: RefCell<DefIdMap<Vec<ty::FragmentInfo>>>,
 }
-impl<'tcx> ctxt<'tcx> {
-    pub fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind {
-        *self.tables.borrow().closure_kinds.get(&def_id).unwrap()
-    }
-
-    pub fn closure_type(&self,
-                        def_id: DefId,
-                        substs: &ClosureSubsts<'tcx>)
-                        -> ty::ClosureTy<'tcx>
-    {
-        self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, &substs.func_substs)
-    }
 
+impl<'tcx> ctxt<'tcx> {
     pub fn type_parameter_def(&self,
                               node_id: NodeId)
                               -> ty::TypeParameterDef<'tcx>
index 1b334e3772244a2058d7866ed59d6f2829ef3329..315268fd0b62655c4bd89122ffb36f5265fdfd70 100644 (file)
@@ -2263,6 +2263,14 @@ pub fn item_path_str(&self, id: DefId) -> String {
         self.with_path(id, |path| ast_map::path_to_string(path))
     }
 
+    pub fn def_path(&self, id: DefId) -> ast_map::DefPath {
+        if id.is_local() {
+            self.map.def_path(id)
+        } else {
+            csearch::def_path(self, id)
+        }
+    }
+
     pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
         F: FnOnce(ast_map::PathElems) -> T,
     {
@@ -2480,6 +2488,18 @@ pub fn populate_implementations_for_trait_if_necessary(&self, trait_id: DefId) {
         def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
     }
 
+    pub fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind {
+        Tables::closure_kind(&self.tables, self, def_id)
+    }
+
+    pub fn closure_type(&self,
+                        def_id: DefId,
+                        substs: &ClosureSubsts<'tcx>)
+                        -> ty::ClosureTy<'tcx>
+    {
+        Tables::closure_type(&self.tables, self, def_id, substs)
+    }
+
     /// Given the def_id of an impl, return the def_id of the trait it implements.
     /// If it implements no trait, return `None`.
     pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
@@ -2800,3 +2820,4 @@ fn is_global(&self) -> bool {
         !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
     }
 }
+
index 2e6cc4faff8d03a72a715e365fe4e1a9656ab9ab..b546438f392a02ea16ec178de7435127454d7443 100644 (file)
@@ -461,7 +461,7 @@ macro_rules! hash { ($e:expr) => { $e.hash(state) }  }
                     tcx.sess.cstore.get_crate_hash(did.krate)
                 };
                 h.as_str().hash(state);
-                did.xxx_node.hash(state);
+                did.index.hash(state);
             };
             let mt = |state: &mut SipHasher, mt: TypeAndMut| {
                 mt.mutbl.hash(state);
index de356e54699c182cdfc21776f0023a59e13e1f99..67ced5d32594d09cfcf6bd26ed3892ce39cc46ac 100644 (file)
@@ -27,7 +27,7 @@
 use syntax::abi;
 use syntax::ast;
 use syntax::parse::token;
-use syntax::ast::{CRATE_NODE_ID};
+use syntax::ast::CRATE_NODE_ID;
 use rustc_front::hir;
 
 pub fn verbose() -> bool {
index d05b5b3e8606a84e65b7fc1de900264f6a7d8b1f..1df3c1609b890894d02e116b5a538ff08c758db0 100644 (file)
@@ -901,20 +901,22 @@ fn expr_refers_to_this_fn(tcx: &ty::ctxt,
         fn expr_refers_to_this_method(tcx: &ty::ctxt,
                                       method: &ty::Method,
                                       id: ast::NodeId) -> bool {
-            let tables = tcx.tables.borrow();
-
             // Check for method calls and overloaded operators.
-            if let Some(m) = tables.method_map.get(&ty::MethodCall::expr(id)) {
+            let opt_m = tcx.tables.borrow().method_map.get(&ty::MethodCall::expr(id)).cloned();
+            if let Some(m) = opt_m {
                 if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) {
                     return true;
                 }
             }
 
             // Check for overloaded autoderef method calls.
-            if let Some(&adjustment::AdjustDerefRef(ref adj)) = tables.adjustments.get(&id) {
+            let opt_adj = tcx.tables.borrow().adjustments.get(&id).cloned();
+            if let Some(adjustment::AdjustDerefRef(adj)) = opt_adj {
                 for i in 0..adj.autoderefs {
                     let method_call = ty::MethodCall::autoderef(id, i as u32);
-                    if let Some(m) = tables.method_map.get(&method_call) {
+                    if let Some(m) = tcx.tables.borrow().method_map
+                                                        .get(&method_call)
+                                                        .cloned() {
                         if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) {
                             return true;
                         }
@@ -927,9 +929,13 @@ fn expr_refers_to_this_method(tcx: &ty::ctxt,
                 hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
                     match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) {
                         Some(def::DefMethod(def_id)) => {
-                            let no_substs = &ty::ItemSubsts::empty();
-                            let ts = tables.item_substs.get(&callee.id).unwrap_or(no_substs);
-                            method_call_refers_to_method(tcx, method, def_id, &ts.substs, id)
+                            let item_substs =
+                                tcx.tables.borrow().item_substs
+                                                   .get(&callee.id)
+                                                   .cloned()
+                                                   .unwrap_or_else(|| ty::ItemSubsts::empty());
+                            method_call_refers_to_method(
+                                tcx, method, def_id, &item_substs.substs, id)
                         }
                         _ => false
                     }
index c50cb5960b1ff89a517fefaed3b7a0aa8ae09ad9..f74144565fc588415c475b944dfbf40193f61072 100644 (file)
@@ -34,7 +34,7 @@
 use rustc::metadata::csearch;
 use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
 use rustc::middle::def::*;
-use rustc::middle::def_id::DefId;
+use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
 
 use syntax::ast::{Name, NodeId};
 use syntax::attr::AttrMetaMethods;
@@ -387,7 +387,7 @@ fn build_reduced_graph_for_item(&mut self, item: &Item, parent: &Rc<Module>) ->
             ItemExternCrate(_) => {
                 // n.b. we don't need to look at the path option here, because cstore already did
                 if let Some(crate_id) = self.session.cstore.find_extern_mod_stmt_cnum(item.id) {
-                    let def_id = DefId { krate: crate_id, xxx_node: 0 };
+                    let def_id = DefId { krate: crate_id, index: CRATE_DEF_INDEX };
                     self.external_exports.insert(def_id);
                     let parent_link = ModuleParentLink(Rc::downgrade(parent), name);
                     let external_module = Rc::new(Module::new(parent_link,
index 2e18b50a45cfe937d020cedb12a86312a5217e2e..eaa947150b04e08bb33ff3e681daed29c25e13bd 100644 (file)
@@ -25,7 +25,7 @@
 use metadata::{encoder, cstore, filesearch, csearch, creader};
 use middle::dependency_format::Linkage;
 use middle::ty::{self, Ty};
-use rustc::front::map::{PathElem, PathElems, PathName};
+use rustc::front::map::DefPath;
 use trans::{CrateContext, CrateTranslation, gensym_name};
 use util::common::time;
 use util::sha2::{Digest, Sha256};
@@ -36,6 +36,7 @@
 use std::ffi::OsString;
 use std::fs::{self, PathExt};
 use std::io::{self, Read, Write};
+use std::iter::once;
 use std::mem;
 use std::path::{Path, PathBuf};
 use std::process::Command;
@@ -44,7 +45,7 @@
 use serialize::hex::ToHex;
 use syntax::ast;
 use syntax::codemap::Span;
-use syntax::parse::token;
+use syntax::parse::token::{self, InternedString};
 use syntax::attr::AttrMetaMethods;
 
 use rustc_front::hir;
@@ -284,8 +285,7 @@ pub fn sanitize(s: &str) -> String {
     return result;
 }
 
-pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI,
-                                           hash: Option<&str>) -> String {
+pub fn mangle<PI: Iterator<Item=InternedString>>(path: PI, hash: Option<&str>) -> String {
     // Follow C++ namespace-mangling style, see
     // http://en.wikipedia.org/wiki/Name_mangling for more info.
     //
@@ -308,8 +308,8 @@ fn push(n: &mut String, s: &str) {
     }
 
     // First, connect each component with <len, name> pairs.
-    for e in path {
-        push(&mut n, &e.name().as_str())
+    for data in path {
+        push(&mut n, &data);
     }
 
     match hash {
@@ -321,11 +321,13 @@ fn push(n: &mut String, s: &str) {
     n
 }
 
-pub fn exported_name(path: PathElems, hash: &str) -> String {
+pub fn exported_name(path: DefPath, hash: &str) -> String {
+    let path = path.into_iter()
+                   .map(|e| e.data.as_interned_str());
     mangle(path, Some(hash))
 }
 
-pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathElems,
+pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: DefPath,
                                       t: Ty<'tcx>, id: ast::NodeId) -> String {
     let mut hash = get_symbol_hash(ccx, t);
 
@@ -353,14 +355,17 @@ pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathEl
 pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                       t: Ty<'tcx>,
                                                       name: &str) -> String {
-    let path = [PathName(token::intern(&t.to_string())),
-                gensym_name(name)];
+    let path = [token::intern(&t.to_string()).as_str(), gensym_name(name).as_str()];
     let hash = get_symbol_hash(ccx, t);
     mangle(path.iter().cloned(), Some(&hash[..]))
 }
 
-pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String {
-    mangle(path.chain(Some(gensym_name(flav))), None)
+pub fn mangle_internal_name_by_path_and_seq(path: DefPath, flav: &str) -> String {
+    let names =
+        path.into_iter()
+            .map(|e| e.data.as_interned_str())
+            .chain(once(gensym_name(flav).as_str())); // append unique version of "flav"
+    mangle(names, None)
 }
 
 pub fn get_linker(sess: &Session) -> (String, Command) {
index 769c124299899fb2936918ecbfcf498be55de2ec..f388f76c744e6ea6bd5e19dbffe80f5b2db97509 100644 (file)
@@ -13,7 +13,8 @@
 use super::escape;
 use super::span_utils::SpanUtils;
 
-use middle::def_id::DefId;
+use metadata::cstore::LOCAL_CRATE;
+use middle::def_id::{CRATE_DEF_INDEX, DefId};
 
 use std::io::Write;
 
@@ -21,7 +22,7 @@
 use syntax::ast::NodeId;
 use syntax::codemap::*;
 
-const ZERO_DEF_ID: DefId = DefId { xxx_node: 0, krate: 0 };
+const CRATE_ROOT_DEF_ID: DefId = DefId { krate: LOCAL_CRATE, index: CRATE_DEF_INDEX };
 
 pub struct Recorder {
     // output file
@@ -381,7 +382,7 @@ pub fn method_str(&mut self,
                       decl_id: Option<DefId>,
                       scope_id: NodeId) {
         let values = match decl_id {
-            Some(decl_id) => svec!(id, name, decl_id.xxx_node, decl_id.krate, scope_id),
+            Some(decl_id) => svec!(id, name, decl_id.index.as_usize(), decl_id.krate, scope_id),
             None => svec!(id, name, "", "", scope_id),
         };
         self.check_and_record(Function,
@@ -436,15 +437,15 @@ pub fn impl_str(&mut self,
                     ref_id: Option<DefId>,
                     trait_id: Option<DefId>,
                     scope_id: NodeId) {
-        let ref_id = ref_id.unwrap_or(ZERO_DEF_ID);
-        let trait_id = trait_id.unwrap_or(ZERO_DEF_ID);
+        let ref_id = ref_id.unwrap_or(CRATE_ROOT_DEF_ID);
+        let trait_id = trait_id.unwrap_or(CRATE_ROOT_DEF_ID);
         self.check_and_record(Impl,
                               span,
                               sub_span,
                               svec!(id,
-                                    ref_id.xxx_node,
+                                    ref_id.index.as_usize(),
                                     ref_id.krate,
-                                    trait_id.xxx_node,
+                                    trait_id.index.as_usize(),
                                     trait_id.krate,
                                     scope_id));
     }
@@ -469,14 +470,11 @@ pub fn use_alias_str(&mut self,
                          mod_id: Option<DefId>,
                          name: &str,
                          parent: NodeId) {
-        let (mod_node, mod_crate) = match mod_id {
-            Some(mod_id) => (mod_id.xxx_node, mod_id.krate),
-            None => (0, 0),
-        };
+        let mod_id = mod_id.unwrap_or(CRATE_ROOT_DEF_ID);
         self.check_and_record(UseAlias,
                               span,
                               sub_span,
-                              svec!(id, mod_node, mod_crate, name, parent));
+                              svec!(id, mod_id.index.as_usize(), mod_id.krate, name, parent));
     }
 
     pub fn use_glob_str(&mut self,
@@ -513,7 +511,7 @@ pub fn inherit_str(&mut self,
         self.check_and_record(Inheritance,
                               span,
                               sub_span,
-                              svec!(base_id.xxx_node,
+                              svec!(base_id.index.as_usize(),
                                     base_id.krate,
                                     deriv_id,
                                     0));
@@ -527,7 +525,7 @@ pub fn fn_call_str(&mut self,
         self.check_and_record(FnCall,
                               span,
                               sub_span,
-                              svec!(id.xxx_node, id.krate, "", scope_id));
+                              svec!(id.index.as_usize(), id.krate, "", scope_id));
     }
 
     pub fn meth_call_str(&mut self,
@@ -536,18 +534,15 @@ pub fn meth_call_str(&mut self,
                          defid: Option<DefId>,
                          declid: Option<DefId>,
                          scope_id: NodeId) {
-        let (dfn, dfk) = match defid {
-            Some(defid) => (defid.xxx_node, defid.krate),
-            None => (0, 0),
-        };
+        let defid = defid.unwrap_or(CRATE_ROOT_DEF_ID);
         let (dcn, dck) = match declid {
-            Some(declid) => (s!(declid.xxx_node), s!(declid.krate)),
+            Some(declid) => (s!(declid.index.as_usize()), s!(declid.krate)),
             None => ("".to_string(), "".to_string()),
         };
         self.check_and_record(MethodCall,
                               span,
                               sub_span,
-                              svec!(dfn, dfk, dcn, dck, scope_id));
+                              svec!(defid.index.as_usize(), defid.krate, dcn, dck, scope_id));
     }
 
     pub fn sub_mod_ref_str(&mut self, span: Span, sub_span: Span, qualname: &str, parent: NodeId) {
@@ -600,6 +595,6 @@ pub fn ref_str(&mut self,
         self.check_and_record(kind,
                               span,
                               sub_span,
-                              svec!(id.xxx_node, id.krate, "", scope_id));
+                              svec!(id.index.as_usize(), id.krate, "", scope_id));
     }
 }
index 61244e32c7d9896dafc02ef0bf11c1a280731877..05b20ac3fb7d436a3d3fead1315e4b7f245f2502 100644 (file)
@@ -1576,7 +1576,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
            param_substs);
 
     let has_env = match closure_env {
-        closure::ClosureEnv::Closure(_) => true,
+        closure::ClosureEnv::Closure(..) => true,
         closure::ClosureEnv::NotClosure => false,
     };
 
@@ -2309,10 +2309,11 @@ fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, id: ast::NodeId,
     match attr::find_export_name_attr(ccx.sess().diagnostic(), attrs) {
         // Use provided name
         Some(name) => name.to_string(),
-        _ => ccx.tcx().map.with_path(id, |path| {
+        _ => {
+            let path = ccx.tcx().map.def_path_from_id(id);
             if attr::contains_name(attrs, "no_mangle") {
                 // Don't mangle
-                path.last().unwrap().to_string()
+                path.last().unwrap().data.to_string()
             } else {
                 match weak_lang_items::link_name(attrs) {
                     Some(name) => name.to_string(),
@@ -2322,7 +2323,7 @@ fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, id: ast::NodeId,
                     }
                 }
             }
-        })
+        }
     }
 }
 
index 89724c38cb2c901f00983c998ffbaf4612edd23e..d3509c2f8133a259be40e758e01bc6b2ef0f8284 100644 (file)
@@ -36,6 +36,7 @@
 
 
 fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+                                        closure_def_id: DefId,
                                         arg_scope_id: ScopeId,
                                         freevars: &[ty::Freevar])
                                         -> Block<'blk, 'tcx>
@@ -43,9 +44,9 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
     let _icx = push_ctxt("closure::load_closure_environment");
 
     // Special case for small by-value selfs.
-    let closure_id = bcx.tcx().map.local_def_id(bcx.fcx.id);
-    let self_type = self_type_for_closure(bcx.ccx(), closure_id, node_id_type(bcx, bcx.fcx.id));
-    let kind = kind_for_closure(bcx.ccx(), closure_id);
+    let closure_ty = node_id_type(bcx, bcx.fcx.id);
+    let self_type = self_type_for_closure(bcx.ccx(), closure_def_id, closure_ty);
+    let kind = kind_for_closure(bcx.ccx(), closure_def_id);
     let llenv = if kind == ty::FnOnceClosureKind &&
             !arg_is_indirect(bcx.ccx(), self_type) {
         let datum = rvalue_scratch_datum(bcx,
@@ -106,7 +107,7 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
 
 pub enum ClosureEnv<'a> {
     NotClosure,
-    Closure(&'a [ty::Freevar]),
+    Closure(DefId, &'a [ty::Freevar]),
 }
 
 impl<'a> ClosureEnv<'a> {
@@ -115,11 +116,11 @@ pub fn load<'blk,'tcx>(self, bcx: Block<'blk, 'tcx>, arg_scope: ScopeId)
     {
         match self {
             ClosureEnv::NotClosure => bcx,
-            ClosureEnv::Closure(freevars) => {
+            ClosureEnv::Closure(def_id, freevars) => {
                 if freevars.is_empty() {
                     bcx
                 } else {
-                    load_closure_environment(bcx, arg_scope, freevars)
+                    load_closure_environment(bcx, def_id, arg_scope, freevars)
                 }
             }
         }
@@ -132,8 +133,6 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                                                    closure_id: DefId,
                                                    substs: &ty::ClosureSubsts<'tcx>)
                                                    -> ValueRef {
-    let closure_node_id = ccx.tcx().map.as_local_node_id(closure_id).unwrap();
-
     // Normalize type so differences in regions and typedefs don't cause
     // duplicate declarations
     let substs = ccx.tcx().erase_regions(substs);
@@ -148,9 +147,8 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         return llfn;
     }
 
-    let symbol = ccx.tcx().map.with_path(closure_node_id, |path| {
-        mangle_internal_name_by_path_and_seq(path, "closure")
-    });
+    let path = ccx.tcx().def_path(closure_id);
+    let symbol = mangle_internal_name_by_path_and_seq(path, "closure");
 
     let function_type = ccx.tcx().mk_closure_from_closure_substs(closure_id, Box::new(substs));
     let llfn = declare::define_internal_rust_fn(ccx, &symbol[..], function_type);
@@ -177,9 +175,14 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
                                     decl: &hir::FnDecl,
                                     body: &hir::Block,
                                     id: ast::NodeId,
+                                    closure_def_id: DefId, // (*)
                                     closure_substs: &'tcx ty::ClosureSubsts<'tcx>)
                                     -> Option<Block<'a, 'tcx>>
 {
+    // (*) Note that in the case of inlined functions, the `closure_def_id` will be the
+    // defid of the closure in its original crate, whereas `id` will be the id of the local
+    // inlined copy.
+
     let param_substs = closure_substs.func_substs;
 
     let ccx = match dest {
@@ -189,10 +192,10 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     let tcx = ccx.tcx();
     let _icx = push_ctxt("closure::trans_closure_expr");
 
-    debug!("trans_closure_expr()");
+    debug!("trans_closure_expr(id={:?}, closure_def_id={:?}, closure_substs={:?})",
+           id, closure_def_id, closure_substs);
 
-    let closure_id = tcx.map.local_def_id(id);
-    let llfn = get_or_create_closure_declaration(ccx, closure_id, closure_substs);
+    let llfn = get_or_create_closure_declaration(ccx, closure_def_id, closure_substs);
 
     // Get the type of this closure. Use the current `param_substs` as
     // the closure substitutions. This makes sense because the closure
@@ -201,7 +204,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
     // of the closure expression.
 
     let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables);
-    let function_type = infcx.closure_type(closure_id, closure_substs);
+    let function_type = infcx.closure_type(closure_def_id, closure_substs);
 
     let freevars: Vec<ty::Freevar> =
         tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
@@ -217,7 +220,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
                   &[],
                   sig.output,
                   function_type.abi,
-                  ClosureEnv::Closure(&freevars));
+                  ClosureEnv::Closure(closure_def_id, &freevars));
 
     // Don't hoist this to the top of the function. It's perfectly legitimate
     // to have a zero-size closure (in which case dest will be `Ignore`) and
index ba50bec2ecd913e856ee6996718c30f21f71f565..d160465c619b95e80f6c2e907b6e33c987d87fe0 100644 (file)
@@ -39,7 +39,6 @@
 use middle::traits;
 use middle::ty::{self, HasTypeFlags, Ty};
 use middle::ty::fold::{TypeFolder, TypeFoldable};
-use rustc::front::map::{PathElem, PathName};
 use rustc_front::hir;
 use util::nodemap::{FnvHashMap, NodeMap};
 
@@ -167,11 +166,11 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
 
 /// Generates a unique symbol based off the name given. This is used to create
 /// unique symbols for things like closures.
-pub fn gensym_name(name: &str) -> PathElem {
+pub fn gensym_name(name: &str) -> ast::Name {
     let num = token::gensym(name).0;
     // use one colon which will get translated to a period by the mangler, and
     // we're guaranteed that `num` is globally unique for this crate.
-    PathName(token::gensym(&format!("{}:{}", name, num)))
+    token::gensym(&format!("{}:{}", name, num))
 }
 
 /*
@@ -1020,7 +1019,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
                    trait_ref);
             ccx.sess().span_fatal(
                 span,
-                "reached the recursion limit during monomorphization");
+                "reached the recursion limit during monomorphization (selection ambiguity)");
         }
         Err(e) => {
             tcx.sess.span_bug(
index 6aa087cce56bdfcfc24dfb73d46da0ac69ec05bb..a7bb4043e7d8187f12b116cdafe37b63275785ec 100644 (file)
@@ -877,9 +877,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
         },
         hir::ExprClosure(_, ref decl, ref body) => {
             match ety.sty {
-                ty::TyClosure(_, ref substs) => {
+                ty::TyClosure(def_id, ref substs) => {
                     closure::trans_closure_expr(closure::Dest::Ignore(cx), decl,
-                                                body, e.id, substs);
+                                                body, e.id, def_id, substs);
                 }
                 _ =>
                     cx.sess().span_bug(
index 94c93a636a12c9f26258016ec3db747833e19a49..a921bbbc43e30f48f3673de735c2a1895fce5cd9 100644 (file)
@@ -346,7 +346,7 @@ fn from_def_id_and_substs<'a, 'tcx>(type_map: &mut TypeMap<'tcx>,
 
             output.push_str(crate_hash.as_str());
             output.push_str("/");
-            output.push_str(&format!("{:x}", def_id.xxx_node));
+            output.push_str(&format!("{:x}", def_id.index.as_usize()));
 
             // Maybe check that there is no self type here.
 
index 476e05d50d20f1da312234893898c0e3232038b7..8d57c24ca90bbddc753ea6ec4d6a4cd38dc47552 100644 (file)
@@ -1195,14 +1195,23 @@ fn make_field(field_name: &str, expr: P<hir::Expr>) -> hir::Field {
                 SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest),
                 Ignore => closure::Dest::Ignore(bcx.ccx())
             };
-            let substs = match expr_ty(bcx, expr).sty {
-                ty::TyClosure(_, ref substs) => substs,
+
+            // NB. To get the id of the closure, we don't use
+            // `local_def_id(id)`, but rather we extract the closure
+            // def-id from the expr's type. This is because this may
+            // be an inlined expression from another crate, and we
+            // want to get the ORIGINAL closure def-id, since that is
+            // the key we need to find the closure-kind and
+            // closure-type etc.
+            let (def_id, substs) = match expr_ty(bcx, expr).sty {
+                ty::TyClosure(def_id, ref substs) => (def_id, substs),
                 ref t =>
                     bcx.tcx().sess.span_bug(
                         expr.span,
                         &format!("closure expr without closure type: {:?}", t)),
             };
-            closure::trans_closure_expr(dest, decl, body, expr.id, substs).unwrap_or(bcx)
+
+            closure::trans_closure_expr(dest, decl, body, expr.id, def_id, substs).unwrap_or(bcx)
         }
         hir::ExprCall(ref f, ref args) => {
             if bcx.tcx().is_method_call(expr.id) {
index 0310a8a6041065c8676465f6455c52119d9065ab..6b9f1559d3793c3eb081cd0b0b60c152d9c06052 100644 (file)
@@ -29,9 +29,9 @@
 use trans::type_of;
 use middle::ty::{self, Ty};
 use middle::subst::Substs;
-use rustc::front::map as hir_map;
 
 use std::cmp;
+use std::iter::once;
 use libc::c_uint;
 use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi};
 use syntax::abi::{PlatformIntrinsic, RustIntrinsic, Rust, RustCall, Stdcall, Fastcall, System};
@@ -610,10 +610,12 @@ fn build_rust_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         let t = tcx.node_id_to_type(id);
         let t = monomorphize::apply_param_substs(tcx, param_substs, &t);
 
-        let ps = ccx.tcx().map.with_path(id, |path| {
-            let abi = Some(hir_map::PathName(special_idents::clownshoe_abi.name));
-            link::mangle(path.chain(abi), hash)
-        });
+        let path =
+            tcx.map.def_path_from_id(id)
+                   .into_iter()
+                   .map(|e| e.data.as_interned_str())
+                   .chain(once(special_idents::clownshoe_abi.name.as_str()));
+        let ps = link::mangle(path, hash);
 
         // Compute the type that the function would have if it were just a
         // normal Rust function. This will be the type of the wrappee fn.
index 67abca78c6eb35e18c38759c302e8561cfed0433..14b65bcb75504346dbaf4dd3254f2c9390c926e2 100644 (file)
@@ -44,7 +44,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
     let csearch_result =
         csearch::maybe_get_item_ast(
             ccx.tcx(), fn_id,
-            Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d)));
+            Box::new(|a,b,c,d,e| astencode::decode_inlined_item(a, b, c, d,e)));
 
     let inline_id = match csearch_result {
         csearch::FoundAst::NotFound => {
index 39f3a29c785f4827585feb2e69a5ce9c7d6303b9..33f798be85e87101c66663c0f44c7ca79ee5fb66 100644 (file)
@@ -110,6 +110,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
             Some(&d) => d, None => 0
         };
 
+        debug!("monomorphic_fn: depth for fn_id={:?} is {:?}", fn_id, depth+1);
+
         // Random cut-off -- code that needs to instantiate the same function
         // recursively more than thirty times can probably safely be assumed
         // to be causing an infinite expansion.
@@ -128,9 +130,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
         mono_ty.hash(&mut state);
 
         hash = format!("h{}", state.finish());
-        ccx.tcx().map.with_path(fn_node_id, |path| {
-            exported_name(path, &hash[..])
-        })
+        let path = ccx.tcx().map.def_path_from_id(fn_node_id);
+        exported_name(path, &hash[..])
     };
 
     debug!("monomorphize_fn mangled to {}", s);
index dab4056b4af8153db5c3b2e8789a5d08f5bed501..3492635a20be420996ccb52854496cdeee57849f 100644 (file)
@@ -39,7 +39,7 @@
 use rustc::metadata::csearch;
 use rustc::metadata::decoder;
 use rustc::middle::def;
-use rustc::middle::def_id::DefId;
+use rustc::middle::def_id::{DefId, DefIndex};
 use rustc::middle::subst::{self, ParamSpace, VecPerParamSpace};
 use rustc::middle::ty;
 use rustc::middle::stability;
@@ -188,7 +188,7 @@ fn clean(&self, cx: &DocContext) -> Crate {
                     attrs: child.attrs.clone(),
                     visibility: Some(hir::Public),
                     stability: None,
-                    def_id: DefId::xxx_local(prim.to_node_id()),
+                    def_id: DefId::local(prim.to_def_index()),
                     inner: PrimitiveItem(prim),
                 });
             }
@@ -1559,8 +1559,9 @@ pub fn to_url_str(&self) -> &'static str {
     /// Creates a rustdoc-specific node id for primitive types.
     ///
     /// These node ids are generally never used by the AST itself.
-    pub fn to_node_id(&self) -> ast::NodeId {
-        u32::MAX - 1 - (*self as u32)
+    pub fn to_def_index(&self) -> DefIndex {
+        let x = u32::MAX - 1 - (*self as u32);
+        DefIndex::new(x as usize)
     }
 }
 
@@ -1744,7 +1745,7 @@ fn clean(&self, cx: &DocContext) -> Item {
         let (name, attrs) = if self.name == unnamed_field.name {
             (None, None)
         } else {
-            (Some(self.name), Some(attr_map.get(&self.did.xxx_node).unwrap()))
+            (Some(self.name), Some(attr_map.get(&self.did).unwrap()))
         };
 
         Item {
index 6937dbf255e2e7c87dab434d18d2bb936b657ac8..d12c5d2c6fb6b3a5350997c12cd385b7c3e9b5ac 100644 (file)
@@ -19,9 +19,8 @@
 use std::iter::repeat;
 
 use rustc::metadata::cstore::LOCAL_CRATE;
-use rustc::middle::def_id::DefId;
+use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
 use syntax::abi::Abi;
-use syntax::ast;
 use rustc_front::hir;
 
 use clean;
@@ -387,7 +386,7 @@ fn primitive_link(f: &mut fmt::Formatter,
         Some(&cnum) => {
             let path = &m.paths[&DefId {
                 krate: cnum,
-                xxx_node: ast::CRATE_NODE_ID,
+                index: CRATE_DEF_INDEX,
             }];
             let loc = match m.extern_locations[&cnum] {
                 (_, render::Remote(ref s)) => Some(s.to_string()),
index 708c8f634f55366678528e81a0f8abccad6afe01..cf03482e18b8a902d541bdb8f2805313bfa7f1ab 100644 (file)
@@ -54,7 +54,7 @@
 use serialize::json::{self, ToJson};
 use syntax::{abi, ast, attr};
 use rustc::metadata::cstore::LOCAL_CRATE;
-use rustc::middle::def_id::DefId;
+use rustc::middle::def_id::{CRATE_DEF_INDEX, DefId};
 use rustc::util::nodemap::DefIdSet;
 use rustc_front::hir;
 
@@ -413,7 +413,7 @@ pub fn run(mut krate: clean::Crate,
     for &(n, ref e) in &krate.externs {
         cache.extern_locations.insert(n, (e.name.clone(),
                                           extern_location(e, &cx.dst)));
-        let did = DefId { krate: n, xxx_node: ast::CRATE_NODE_ID };
+        let did = DefId { krate: n, index: CRATE_DEF_INDEX };
         cache.paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
     }
 
@@ -1034,7 +1034,7 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                     ref t => {
                         match t.primitive_type() {
                             Some(prim) => {
-                                let did = DefId::xxx_local(prim.to_node_id()); // TODO
+                                let did = DefId::local(prim.to_def_index());
                                 self.parent_stack.push(did);
                                 true
                             }
@@ -1079,8 +1079,8 @@ fn fold_item(&mut self, item: clean::Item) -> Option<clean::Item> {
                             ref t => {
                                 t.primitive_type().and_then(|t| {
                                     self.primitive_locations.get(&t).map(|n| {
-                                        let id = t.to_node_id();
-                                        DefId { krate: *n, xxx_node: id }
+                                        let id = t.to_def_index();
+                                        DefId { krate: *n, index: id }
                                     })
                                 })
                             }
@@ -1421,7 +1421,7 @@ fn href(&self, cx: &Context) -> Option<String> {
                          root = root,
                          path = path[..path.len() - 1].join("/"),
                          file = item_path(self.item),
-                         goto = self.item.def_id.xxx_node))
+                         goto = self.item.def_id.index.as_usize()))
         }
     }
 }
@@ -1481,7 +1481,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
                 Some(l) => {
                     try!(write!(fmt, "<a id='src-{}' class='srclink' \
                                        href='{}' title='{}'>[src]</a>",
-                                self.item.def_id.xxx_node, l, "goto source code"));
+                                self.item.def_id.index.as_usize(), l, "goto source code"));
                 }
                 None => {}
             }
@@ -2337,7 +2337,7 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl) -> f
         _ => {
             if let Some(prim) = target.primitive_type() {
                 if let Some(c) = cache().primitive_locations.get(&prim) {
-                    let did = DefId { krate: *c, xxx_node: prim.to_node_id() };
+                    let did = DefId { krate: *c, index: prim.to_def_index() };
                     try!(render_assoc_items(w, cx, did, what));
                 }
             }
index 45e1d00586327233d60b56716020fcd04e3e1dc6..d186918f44aaae4925b1604b9243183b80c35a8e 100644 (file)
@@ -167,13 +167,13 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
 
 impl Encodable for Ident {
     fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
-        s.emit_str(&self.name.as_str())
+        self.name.encode(s)
     }
 }
 
 impl Decodable for Ident {
     fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
-        Ok(str_to_ident(&try!(d.read_str())[..]))
+        Ok(Ident::with_empty_ctxt(try!(Name::decode(d))))
     }
 }