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,
}
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>) {
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);
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, _) => {
}
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;
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;
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;
}
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));
}
}
--- /dev/null
+// 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
+}
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};
pub mod blocks;
mod collector;
+pub mod definitions;
#[derive(Clone, Copy, PartialEq, Debug)]
pub enum PathElem {
/// 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 `{:?}`",
}
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 {
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
Map {
forest: forest,
map: RefCell::new(map),
- definitions_map: RefCell::new(definitions_map),
+ definitions: RefCell::new(definitions),
}
}
/// 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 {
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
}
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;
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
// 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;
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;
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),
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) {
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)
});
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;
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.
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)
};
decoder::each_child_of_item(cstore.intr.clone(),
&*crate_data,
- def_id.xxx_node,
+ def_id.index,
get_crate_data,
callback)
}
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());
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> {
-> 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)
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)
}
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>,
-> 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)
}
-> 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)
{
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)
{
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>,
{
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>(
{
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,
-> 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)
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,
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,
-> 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,
-> 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)
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 {
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()
+}
+
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,
}
}
+ 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")
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
}
}
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> {
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)
}
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()
})
}
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()
}
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()
}
}
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);
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,
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;
}
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)),
// 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);
} 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);
}
pub fn get_predicates<'tcx>(cdata: Cmd,
- item_id: ast::NodeId,
+ item_id: DefIndex,
tcx: &ty::ctxt<'tcx>)
-> ty::GenericPredicates<'tcx>
{
}
pub fn get_super_predicates<'tcx>(cdata: Cmd,
- item_id: ast::NodeId,
+ item_id: DefIndex,
tcx: &ty::ctxt<'tcx>)
-> ty::GenericPredicates<'tcx>
{
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 {
}
}
-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);
})
}
-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);
}
pub fn get_impl_polarity<'tcx>(cdata: Cmd,
- id: ast::NodeId)
+ id: DefIndex)
-> Option<hir::ImplPolarity>
{
let item_doc = cdata.lookup_item(id);
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);
}
pub fn get_impl_trait<'tcx>(cdata: Cmd,
- id: ast::NodeId,
+ id: DefIndex,
tcx: &ty::ctxt<'tcx>)
-> Option<ty::TraitRef<'tcx>>
{
}
}
-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;
/// 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)
})
}
};
// 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.
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);
};
// 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
/// 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),
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))
}
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
}
}
/// 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);
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') => {
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);
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),
}
}
-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| {
}).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);
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())
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);
[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())
}
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;
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 {
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 => {
/// 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);
}
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()
}
}
}
-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| {
// 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")
// 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 });
}
}
}
pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
- id: ast::NodeId,
+ id: DefIndex,
mut callback: F)
where F: FnMut(DefId),
{
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));
}
}
}
-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 => {
}).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
}).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) => {
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,
}
}
-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,
}
}
-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,
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);
}
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();
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);
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
}
}).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,
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)
+ })
+}
+
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};
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;
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>,
}
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,
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;
}
}
- 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'
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);
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);
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);
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);
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');
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');
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));
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 {
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);
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);
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,
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);
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);
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);
}
/* 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);
}
}
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);
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);
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) => {
}
}
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);
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);
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);
}
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,
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, _) => {
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);
});
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);
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,
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();
}
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();
}
}
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 => {}
}
}
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();
}
// 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();
}
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();
// 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);
}
}
}
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));
- }
-}
#![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],
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)
}
}
'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();
}
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}
}
'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);
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' => {
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);
}
'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() != '.' {
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 {
'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)
}
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();
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();
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 {
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;
fn tr(&self, dcx: &DecodeContext) -> Self;
}
-trait tr_intern {
- fn tr_intern(&self, dcx: &DecodeContext) -> DefId;
-}
-
// ______________________________________________________________________
// Top-level methods.
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: {:?}::?",
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,
/// 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
}
}
-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)
}
}
-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();
}
}
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>]);
}
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)));
}
})
}
- 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);
-> 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;
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()
}
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()
}
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 {
-> 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()
}
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
/// 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;
}
}
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);
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 { .. }, _) => {
}
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
}
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
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
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 {
}
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
{
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,
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)
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
});
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;
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);
}
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};
// (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
// 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
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
// 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()
}
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;
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> {
/// 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>
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,
{
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> {
!self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
}
}
+
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);
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 {
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;
}
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
}
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;
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,
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};
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;
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;
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.
//
}
// 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 {
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);
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) {
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;
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
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,
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));
}
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,
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));
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,
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) {
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));
}
}
param_substs);
let has_env = match closure_env {
- closure::ClosureEnv::Closure(_) => true,
+ closure::ClosureEnv::Closure(..) => true,
closure::ClosureEnv::NotClosure => false,
};
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(),
}
}
}
- })
+ }
}
}
fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
+ closure_def_id: DefId,
arg_scope_id: ScopeId,
freevars: &[ty::Freevar])
-> 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,
pub enum ClosureEnv<'a> {
NotClosure,
- Closure(&'a [ty::Freevar]),
+ Closure(DefId, &'a [ty::Freevar]),
}
impl<'a> ClosureEnv<'a> {
{
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)
}
}
}
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);
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);
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 {
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
// 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());
&[],
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
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};
/// 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))
}
/*
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(
},
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(
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.
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) {
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};
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.
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 => {
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.
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);
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;
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),
});
}
/// 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)
}
}
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 {
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;
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()),
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;
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));
}
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
}
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 }
})
})
}
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()))
}
}
}
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 => {}
}
_ => {
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));
}
}
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))))
}
}