1
Fork 0

Convert DefId to use DefIndex, which is an index into a list of

paths, and construct paths for all definitions. Also, stop rewriting
DefIds for closures, and instead just load the closure data from
the original def-id, which may be in another crate.
This commit is contained in:
Niko Matsakis 2015-09-17 14:29:59 -04:00
parent a6fee06741
commit 01f32ace03
40 changed files with 1125 additions and 783 deletions

View file

@ -14,16 +14,16 @@ use super::MapEntry::*;
use rustc_front::hir::*; use rustc_front::hir::*;
use rustc_front::util; use rustc_front::util;
use rustc_front::visit::{self, Visitor}; use rustc_front::visit::{self, Visitor};
use middle::def_id::{CRATE_DEF_INDEX, DefIndex};
use std::iter::repeat; use std::iter::repeat;
use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID}; use syntax::ast::{NodeId, CRATE_NODE_ID, DUMMY_NODE_ID};
use syntax::codemap::Span; use syntax::codemap::Span;
use util::nodemap::NodeSet;
/// A Visitor that walks over an AST and collects Node's into an AST /// A Visitor that walks over an AST and collects Node's into an AST
/// Map. /// Map.
pub struct NodeCollector<'ast> { pub struct NodeCollector<'ast> {
pub map: Vec<MapEntry<'ast>>, pub map: Vec<MapEntry<'ast>>,
pub definitions_map: NodeSet, pub definitions: Definitions,
pub parent_node: NodeId, pub parent_node: NodeId,
} }
@ -31,35 +31,59 @@ impl<'ast> NodeCollector<'ast> {
pub fn root() -> NodeCollector<'ast> { pub fn root() -> NodeCollector<'ast> {
let mut collector = NodeCollector { let mut collector = NodeCollector {
map: vec![], map: vec![],
definitions_map: NodeSet(), definitions: Definitions::new(),
parent_node: CRATE_NODE_ID, parent_node: CRATE_NODE_ID,
}; };
collector.insert_entry(CRATE_NODE_ID, RootCrate); 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 collector
} }
pub fn extend(parent: &'ast InlinedParent, pub fn extend(parent: &'ast InlinedParent,
parent_node: NodeId, parent_node: NodeId,
parent_def_path: DefPath,
map: Vec<MapEntry<'ast>>, map: Vec<MapEntry<'ast>>,
definitions_map: NodeSet) definitions: Definitions)
-> NodeCollector<'ast> { -> NodeCollector<'ast> {
let mut collector = NodeCollector { let mut collector = NodeCollector {
map: map, map: map,
definitions_map: definitions_map, parent_node: parent_node,
parent_node: parent_node definitions: definitions,
}; };
collector.insert_entry(parent_node, RootInlinedParent(parent)); collector.insert_entry(parent_node, RootInlinedParent(parent));
collector.create_def(parent_node, DefPathData::InlinedRoot(parent_def_path));
collector collector
} }
fn create_def(&mut self, node: NodeId) { fn parent_def(&self) -> Option<DefIndex> {
let is_new = self.definitions_map.insert(node); let mut parent_node = Some(self.parent_node);
assert!(is_new, while let Some(p) = parent_node {
"two entries for node id `{}` -- previous is `{:?}`", if let Some(q) = self.definitions.opt_def_index(p) {
node, node); 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>) { fn insert_entry(&mut self, id: NodeId, entry: MapEntry<'ast>) {
@ -71,6 +95,11 @@ impl<'ast> NodeCollector<'ast> {
self.map[id as usize] = entry; 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>) { fn insert(&mut self, id: NodeId, node: Node<'ast>) {
let entry = MapEntry::from_node(self.parent_node, node); let entry = MapEntry::from_node(self.parent_node, node);
self.insert_entry(id, entry); self.insert_entry(id, entry);
@ -85,47 +114,61 @@ impl<'ast> NodeCollector<'ast> {
impl<'ast> Visitor<'ast> for NodeCollector<'ast> { impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
fn visit_item(&mut self, i: &'ast Item) { 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; let parent_node = self.parent_node;
self.parent_node = i.id; self.parent_node = i.id;
self.create_def(i.id);
match i.node { match i.node {
ItemImpl(..) => { } ItemImpl(..) => {}
ItemEnum(ref enum_definition, _) => { ItemEnum(ref enum_definition, _) => {
for v in &enum_definition.variants { for v in &enum_definition.variants {
self.insert(v.node.id, NodeVariant(&**v)); let variant_def_index =
self.create_def(v.node.id); self.insert_def(v.node.id,
NodeVariant(&**v),
DefPathData::EnumVariant(v.node.name));
match v.node.kind { match v.node.kind {
TupleVariantKind(ref args) => { TupleVariantKind(ref args) => {
for arg in 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) => { StructVariantKind(ref def) => {
for field in &def.fields { 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, _) => { ItemStruct(ref struct_def, _) => {
// If this is a tuple-like struct, register the constructor. // If this is a tuple-like struct, register the constructor.
match struct_def.ctor_id { if let Some(ctor_id) = struct_def.ctor_id {
Some(ctor_id) => { self.insert_def(ctor_id,
self.insert(ctor_id, NodeStructCtor(&**struct_def)); NodeStructCtor(&**struct_def),
self.create_def(ctor_id); DefPathData::StructCtor);
}
None => {}
} }
for field in &struct_def.fields { 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, _) => { ItemTrait(_, _, ref bounds, _) => {
@ -152,8 +195,9 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
} }
fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) { fn visit_foreign_item(&mut self, foreign_item: &'ast ForeignItem) {
self.insert(foreign_item.id, NodeForeignItem(foreign_item)); self.insert_def(foreign_item.id,
self.create_def(foreign_item.id); NodeForeignItem(foreign_item),
DefPathData::Value(foreign_item.name));
let parent_node = self.parent_node; let parent_node = self.parent_node;
self.parent_node = foreign_item.id; self.parent_node = foreign_item.id;
@ -163,58 +207,71 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
fn visit_generics(&mut self, generics: &'ast Generics) { fn visit_generics(&mut self, generics: &'ast Generics) {
for ty_param in generics.ty_params.iter() { for ty_param in generics.ty_params.iter() {
self.create_def(ty_param.id); self.insert_def(ty_param.id,
self.insert(ty_param.id, NodeTyParam(ty_param)); NodeTyParam(ty_param),
DefPathData::TypeParam(ty_param.name));
} }
visit::walk_generics(self, generics); visit::walk_generics(self, generics);
} }
fn visit_trait_item(&mut self, ti: &'ast TraitItem) { 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.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 { match ti.node {
ConstTraitItem(_, Some(ref expr)) => { 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); visit::walk_trait_item(self, ti);
self.parent_node = parent_node; self.parent_node = parent_node;
} }
fn visit_impl_item(&mut self, ii: &'ast ImplItem) { fn visit_impl_item(&mut self, ii: &'ast ImplItem) {
self.insert(ii.id, NodeImplItem(ii)); let def_data = match ii.node {
self.create_def(ii.id); 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 { match ii.node {
ConstImplItem(_, ref expr) => { 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); visit::walk_impl_item(self, ii);
self.parent_node = parent_node; self.parent_node = parent_node;
} }
fn visit_pat(&mut self, pat: &'ast Pat) { fn visit_pat(&mut self, pat: &'ast Pat) {
let maybe_binding = match pat.node { let maybe_binding = match pat.node {
PatIdent(..) => true, PatIdent(_, id, _) => Some(id.node),
_ => false _ => None
}; };
self.insert(pat.id, if let Some(id) = maybe_binding {
if maybe_binding {NodeLocal(pat)} else {NodePat(pat)}); self.insert_def(pat.id, NodeLocal(pat), DefPathData::Binding(id.name));
} else {
if maybe_binding { self.insert(pat.id, NodePat(pat));
self.create_def(pat.id);
} }
let parent_node = self.parent_node; let parent_node = self.parent_node;
@ -227,8 +284,8 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
self.insert(expr.id, NodeExpr(expr)); self.insert(expr.id, NodeExpr(expr));
match expr.node { match expr.node {
ExprClosure(..) => self.create_def(expr.id), ExprClosure(..) => { self.create_def(expr.id, DefPathData::ClosureExpr); }
_ => (), _ => { }
} }
let parent_node = self.parent_node; let parent_node = self.parent_node;
@ -276,12 +333,12 @@ impl<'ast> Visitor<'ast> for NodeCollector<'ast> {
} }
fn visit_lifetime_def(&mut self, def: &'ast LifetimeDef) { 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); self.visit_lifetime(&def.lifetime);
} }
fn visit_macro_def(&mut self, macro_def: &'ast MacroDef) { 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));
} }
} }

View file

@ -0,0 +1,263 @@
// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use metadata::cstore::LOCAL_CRATE;
use middle::def_id::{DefId, DefIndex};
use rustc_data_structures::fnv::FnvHashMap;
use rustc_front::hir;
use syntax::ast;
use syntax::parse::token::InternedString;
use util::nodemap::NodeMap;
#[derive(Clone)]
pub struct Definitions {
data: Vec<DefData>,
key_map: FnvHashMap<DefKey, DefIndex>,
node_map: NodeMap<DefIndex>,
}
/// A unique identifier that we can use to lookup a definition
/// precisely. It combines the index of the definition's parent (if
/// any) with a `DisambiguatedDefPathData`.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct DefKey {
/// Parent path.
pub parent: Option<DefIndex>,
/// Identifier of this node.
pub disambiguated_data: DisambiguatedDefPathData,
}
/// Pair of `DefPathData` and an integer disambiguator. The integer is
/// normally 0, but in the event that there are multiple defs with the
/// same `parent` and `data`, we use this field to disambiguate
/// between them. This introduces some artificial ordering dependency
/// but means that if you have (e.g.) two impls for the same type in
/// the same module, they do get distinct def-ids.
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub struct DisambiguatedDefPathData {
pub data: DefPathData,
pub disambiguator: u32
}
/// For each definition, we track the following data. A definition
/// here is defined somewhat circularly as "something with a def-id",
/// but it generally corresponds to things like structs, enums, etc.
/// There are also some rather random cases (like const initializer
/// expressions) that are mostly just leftovers.
#[derive(Clone, Debug)]
pub struct DefData {
pub key: DefKey,
/// Local ID within the HIR.
pub node_id: ast::NodeId,
}
pub type DefPath = Vec<DisambiguatedDefPathData>;
#[derive(Clone, Debug, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)]
pub enum DefPathData {
// Root: these should only be used for the root nodes, because
// they are treated specially by the `def_path` function.
CrateRoot,
InlinedRoot(DefPath),
// Catch-all for random DefId things like DUMMY_NODE_ID
Misc,
// Different kinds of items and item-like things:
Impl,
Type(ast::Name),
Mod(ast::Name),
Value(ast::Name),
MacroDef(ast::Name),
ClosureExpr,
// Subportions of items
TypeParam(ast::Name),
LifetimeDef(ast::Name),
EnumVariant(ast::Name),
PositionalField,
Field(hir::StructFieldKind),
StructCtor, // implicit ctor for a tuple-like struct
Initializer, // initializer for a const
Binding(ast::Name), // pattern binding
// An external crate that does not have an `extern crate` in this
// crate.
DetachedCrate(ast::Name),
}
impl Definitions {
pub fn new() -> Definitions {
Definitions {
data: vec![],
key_map: FnvHashMap(),
node_map: NodeMap(),
}
}
pub fn len(&self) -> usize {
self.data.len()
}
pub fn def_key(&self, index: DefIndex) -> DefKey {
self.data[index.as_usize()].key.clone()
}
/// Returns the path from the crate root to `index`. The root
/// nodes are not included in the path (i.e., this will be an
/// empty vector for the crate root). For an inlined item, this
/// will be the path of the item in the external crate (but the
/// path will begin with the path to the external crate).
pub fn def_path(&self, index: DefIndex) -> DefPath {
make_def_path(index, |p| self.def_key(p))
}
pub fn opt_def_index(&self, node: ast::NodeId) -> Option<DefIndex> {
self.node_map.get(&node).cloned()
}
pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option<DefId> {
self.opt_def_index(node).map(DefId::local)
}
pub fn as_local_node_id(&self, def_id: DefId) -> Option<ast::NodeId> {
if def_id.krate == LOCAL_CRATE {
assert!(def_id.index.as_usize() < self.data.len());
Some(self.data[def_id.index.as_usize()].node_id)
} else {
None
}
}
pub fn create_def_with_parent(&mut self,
parent: Option<DefIndex>,
node_id: ast::NodeId,
data: DefPathData)
-> DefIndex {
assert!(!self.node_map.contains_key(&node_id),
"adding a def'n for node-id {:?} and data {:?} but a previous def'n exists: {:?}",
node_id,
data,
self.data[self.node_map[&node_id].as_usize()]);
// Find a unique DefKey. This basically means incrementing the disambiguator
// until we get no match.
let mut key = DefKey {
parent: parent,
disambiguated_data: DisambiguatedDefPathData {
data: data,
disambiguator: 0
}
};
while self.key_map.contains_key(&key) {
key.disambiguated_data.disambiguator += 1;
}
// Create the definition.
let index = DefIndex::new(self.data.len());
self.data.push(DefData { key: key.clone(), node_id: node_id });
self.node_map.insert(node_id, index);
self.key_map.insert(key, index);
index
}
}
impl DefPathData {
pub fn as_interned_str(&self) -> InternedString {
use self::DefPathData::*;
match *self {
Type(name) |
Mod(name) |
Value(name) |
MacroDef(name) |
TypeParam(name) |
LifetimeDef(name) |
EnumVariant(name) |
DetachedCrate(name) |
Binding(name) => {
name.as_str()
}
Field(hir::StructFieldKind::NamedField(name, _)) => {
name.as_str()
}
PositionalField |
Field(hir::StructFieldKind::UnnamedField(_)) => {
InternedString::new("<field>")
}
// note that this does not show up in user printouts
CrateRoot => {
InternedString::new("<root>")
}
// note that this does not show up in user printouts
InlinedRoot(_) => {
InternedString::new("<inlined-root>")
}
Misc => {
InternedString::new("?")
}
Impl => {
InternedString::new("<impl>")
}
ClosureExpr => {
InternedString::new("<closure>")
}
StructCtor => {
InternedString::new("<constructor>")
}
Initializer => {
InternedString::new("<initializer>")
}
}
}
pub fn to_string(&self) -> String {
self.as_interned_str().to_string()
}
}
pub fn make_def_path<FN>(start_index: DefIndex, mut get_key: FN) -> DefPath
where FN: FnMut(DefIndex) -> DefKey
{
let mut result = vec![];
let mut index = Some(start_index);
while let Some(p) = index {
let key = get_key(p);
match key.disambiguated_data.data {
DefPathData::CrateRoot => {
assert!(key.parent.is_none());
break;
}
DefPathData::InlinedRoot(ref p) => {
assert!(key.parent.is_none());
result.extend(p.iter().cloned().rev());
break;
}
_ => {
result.push(key.disambiguated_data);
index = key.parent;
}
}
}
result.reverse();
result
}

View file

@ -12,12 +12,11 @@ pub use self::Node::*;
pub use self::PathElem::*; pub use self::PathElem::*;
use self::MapEntry::*; use self::MapEntry::*;
use self::collector::NodeCollector; 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;
use metadata::inline::InlinedItem as II; use metadata::inline::InlinedItem as II;
use middle::def_id::DefId; use middle::def_id::DefId;
use util::nodemap::NodeSet;
use syntax::abi; use syntax::abi;
use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID}; use syntax::ast::{self, Name, NodeId, DUMMY_NODE_ID};
@ -39,6 +38,7 @@ use std::slice;
pub mod blocks; pub mod blocks;
mod collector; mod collector;
pub mod definitions;
#[derive(Clone, Copy, PartialEq, Debug)] #[derive(Clone, Copy, PartialEq, Debug)]
pub enum PathElem { pub enum PathElem {
@ -268,10 +268,28 @@ pub struct Map<'ast> {
/// plain old integers. /// plain old integers.
map: RefCell<Vec<MapEntry<'ast>>>, map: RefCell<Vec<MapEntry<'ast>>>,
definitions_map: RefCell<NodeSet>, definitions: RefCell<Definitions>,
} }
impl<'ast> Map<'ast> { 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 { pub fn local_def_id(&self, node: NodeId) -> DefId {
self.opt_local_def_id(node).unwrap_or_else(|| { self.opt_local_def_id(node).unwrap_or_else(|| {
panic!("local_def_id: no entry for `{}`, which has a map of `{:?}`", panic!("local_def_id: no entry for `{}`, which has a map of `{:?}`",
@ -280,30 +298,27 @@ impl<'ast> Map<'ast> {
} }
pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> { pub fn opt_local_def_id(&self, node: NodeId) -> Option<DefId> {
if self.definitions_map.borrow().contains(&node) { self.definitions.borrow().opt_local_def_id(node)
Some(DefId::xxx_local(node))
} else {
None
}
} }
pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> { pub fn as_local_node_id(&self, def_id: DefId) -> Option<NodeId> {
if def_id.krate == LOCAL_CRATE { self.definitions.borrow().as_local_node_id(def_id)
assert!(self.definitions_map.borrow().contains(&def_id.xxx_node));
Some(def_id.xxx_node)
} else {
None
}
} }
/// for default methods, we create a fake node-id; this method /// for default methods, we create a fake node-id; this method
/// adds that fake node-id to the def-id tables /// adds that fake node-id to the def-id tables
pub fn synthesize_default_method_def_id(&self, pub fn synthesize_default_method_def_id(&self,
_impl_def_id: DefId, impl_def_id: DefId,
new_method_id: NodeId) new_method_id: NodeId,
method_name: Name)
-> DefId { -> DefId {
self.definitions_map.borrow_mut().insert(new_method_id); assert!(impl_def_id.is_local());
DefId::xxx_local(new_method_id) 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 { fn entry_count(&self) -> usize {
@ -791,7 +806,7 @@ impl<F: FoldOps> Folder for IdAndSpanUpdater<F> {
pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> { pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
let mut collector = NodeCollector::root(); let mut collector = NodeCollector::root();
visit::walk_crate(&mut collector, &forest.krate); visit::walk_crate(&mut collector, &forest.krate);
let NodeCollector { map, definitions_map, .. } = collector; let NodeCollector { map, definitions, .. } = collector;
if log_enabled!(::log::DEBUG) { if log_enabled!(::log::DEBUG) {
// This only makes sense for ordered stores; note the // This only makes sense for ordered stores; note the
@ -812,7 +827,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
Map { Map {
forest: forest, forest: forest,
map: RefCell::new(map), map: RefCell::new(map),
definitions_map: RefCell::new(definitions_map), definitions: RefCell::new(definitions),
} }
} }
@ -821,6 +836,7 @@ pub fn map_crate<'ast>(forest: &'ast mut Forest) -> Map<'ast> {
/// the item itself. /// the item itself.
pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
path: Vec<PathElem>, path: Vec<PathElem>,
def_path: DefPath,
ii: InlinedItem, ii: InlinedItem,
fold_ops: F) fold_ops: F)
-> &'ast InlinedItem { -> &'ast InlinedItem {
@ -845,14 +861,16 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>,
let ii_parent_id = fld.new_id(DUMMY_NODE_ID); let ii_parent_id = fld.new_id(DUMMY_NODE_ID);
let mut collector = let mut collector =
NodeCollector::extend(ii_parent, NodeCollector::extend(
ii_parent_id, ii_parent,
mem::replace(&mut *map.map.borrow_mut(), vec![]), ii_parent_id,
mem::replace(&mut *map.definitions_map.borrow_mut(), NodeSet())); 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); ii_parent.ii.visit(&mut collector);
*map.map.borrow_mut() = collector.map; *map.map.borrow_mut() = collector.map;
*map.definitions_map.borrow_mut() = collector.definitions_map; *map.definitions.borrow_mut() = collector.definitions;
&ii_parent.ii &ii_parent.ii
} }

View file

@ -43,9 +43,15 @@ pub const tag_items_data_parent_item: usize = 0x28;
pub const tag_items_data_item_is_tuple_struct_ctor: usize = 0x29; 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; pub const tag_meta_item_name_value: usize = 0x2f;
@ -137,8 +143,7 @@ enum_from_u32! {
tag_table_adjustments = 0x61, tag_table_adjustments = 0x61,
tag_table_moves_map = 0x62, tag_table_moves_map = 0x62,
tag_table_capture_map = 0x63, tag_table_capture_map = 0x63,
tag_table_closure_tys = 0x64, // GAP 0x64, 0x65
tag_table_closure_kinds = 0x65,
tag_table_upvar_capture_map = 0x66, tag_table_upvar_capture_map = 0x66,
tag_table_capture_modes = 0x67, tag_table_capture_modes = 0x67,
// GAP 0x68 // GAP 0x68
@ -162,12 +167,12 @@ pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only
// tag_lang_items // tag_lang_items
// - tag_lang_items_item // - tag_lang_items_item
// - tag_lang_items_item_id: u32 // - 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: usize = 0x107; // top-level only
pub const tag_lang_items_item: usize = 0x73; pub const tag_lang_items_item: usize = 0x73;
pub const tag_lang_items_item_id: usize = 0x74; 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_lang_items_missing: usize = 0x76;
pub const tag_item_unnamed_field: usize = 0x77; pub const tag_item_unnamed_field: usize = 0x77;
@ -215,7 +220,7 @@ pub struct LinkMeta {
pub const tag_struct_fields: usize = 0x10d; // top-level only pub const tag_struct_fields: usize = 0x10d; // top-level only
pub const tag_struct_field: usize = 0x8a; 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; pub const tag_attribute_is_sugared_doc: usize = 0x8c;

View file

@ -325,6 +325,7 @@ impl<'a> CrateReader<'a> {
let cmeta = Rc::new(cstore::crate_metadata { let cmeta = Rc::new(cstore::crate_metadata {
name: name.to_string(), name: name.to_string(),
local_path: RefCell::new(SmallVector::zero()), local_path: RefCell::new(SmallVector::zero()),
local_def_path: RefCell::new(vec![]),
index: decoder::load_index(metadata.as_slice()), index: decoder::load_index(metadata.as_slice()),
data: metadata, data: metadata,
cnum_map: RefCell::new(cnum_map), cnum_map: RefCell::new(cnum_map),
@ -548,7 +549,8 @@ impl<'a> CrateReader<'a> {
self.sess.abort_if_errors(); 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)); .map(|id| decoder::get_symbol_from_buf(ekrate.metadata.as_slice(), id));
match (ekrate.dylib.as_ref(), registrar) { match (ekrate.dylib.as_ref(), registrar) {
@ -751,6 +753,9 @@ impl<'a, 'b> LocalCrateReader<'a, 'b> {
i.span, i.span,
PathKind::Crate, PathKind::Crate,
true); 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| { self.ast_map.with_path(i.id, |path| {
cmeta.update_local_path(path) cmeta.update_local_path(path)
}); });

View file

@ -14,7 +14,7 @@ use front::map as ast_map;
use metadata::cstore; use metadata::cstore;
use metadata::decoder; use metadata::decoder;
use metadata::inline::InlinedItem; use metadata::inline::InlinedItem;
use middle::def_id::DefId; use middle::def_id::{DefId, DefIndex};
use middle::lang_items; use middle::lang_items;
use middle::ty; use middle::ty;
use util::nodemap::FnvHashMap; use util::nodemap::FnvHashMap;
@ -33,7 +33,7 @@ pub struct MethodInfo {
pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String { pub fn get_symbol(cstore: &cstore::CStore, def: DefId) -> String {
let cdata = cstore.get_crate_data(def.krate); 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. /// Iterates over all the language items in the given crate.
@ -41,7 +41,7 @@ pub fn each_lang_item<F>(cstore: &cstore::CStore,
cnum: ast::CrateNum, cnum: ast::CrateNum,
f: F) f: F)
-> bool where -> bool where
F: FnMut(ast::NodeId, usize) -> bool, F: FnMut(DefIndex, usize) -> bool,
{ {
let crate_data = cstore.get_crate_data(cnum); let crate_data = cstore.get_crate_data(cnum);
decoder::each_lang_item(&*crate_data, f) decoder::each_lang_item(&*crate_data, f)
@ -59,7 +59,7 @@ pub fn each_child_of_item<F>(cstore: &cstore::CStore,
}; };
decoder::each_child_of_item(cstore.intr.clone(), decoder::each_child_of_item(cstore.intr.clone(),
&*crate_data, &*crate_data,
def_id.xxx_node, def_id.index,
get_crate_data, get_crate_data,
callback) callback)
} }
@ -83,7 +83,7 @@ pub fn each_top_level_item_of_crate<F>(cstore: &cstore::CStore,
pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> { pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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| { cdata.with_local_path(|cpath| {
let mut r = Vec::with_capacity(cpath.len() + path.len()); let mut r = Vec::with_capacity(cpath.len() + path.len());
@ -96,7 +96,7 @@ pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec<ast_map::PathElem> {
pub fn get_item_name(tcx: &ty::ctxt, def: DefId) -> ast::Name { pub fn get_item_name(tcx: &ty::ctxt, def: DefId) -> ast::Name {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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> { pub enum FoundAst<'ast> {
@ -113,14 +113,14 @@ pub fn maybe_get_item_ast<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId,
-> FoundAst<'tcx> { -> FoundAst<'tcx> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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. /// Returns information about the given implementation.
pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: DefId) pub fn get_impl_items(cstore: &cstore::CStore, impl_def_id: DefId)
-> Vec<ty::ImplOrTraitItemId> { -> Vec<ty::ImplOrTraitItemId> {
let cdata = cstore.get_crate_data(impl_def_id.krate); 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) pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@ -128,7 +128,7 @@ pub fn get_impl_or_trait_item<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
let cdata = tcx.sess.cstore.get_crate_data(def.krate); let cdata = tcx.sess.cstore.get_crate_data(def.krate);
decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(), decoder::get_impl_or_trait_item(tcx.sess.cstore.intr.clone(),
&*cdata, &*cdata,
def.xxx_node, def.index,
tcx) tcx)
} }
@ -136,24 +136,24 @@ pub fn get_trait_name(cstore: &cstore::CStore, def: DefId) -> ast::Name {
let cdata = cstore.get_crate_data(def.krate); let cdata = cstore.get_crate_data(def.krate);
decoder::get_trait_name(cstore.intr.clone(), decoder::get_trait_name(cstore.intr.clone(),
&*cdata, &*cdata,
def.xxx_node) def.index)
} }
pub fn is_static_method(cstore: &cstore::CStore, def: DefId) -> bool { pub fn is_static_method(cstore: &cstore::CStore, def: DefId) -> bool {
let cdata = cstore.get_crate_data(def.krate); 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) pub fn get_trait_item_def_ids(cstore: &cstore::CStore, def: DefId)
-> Vec<ty::ImplOrTraitItemId> { -> Vec<ty::ImplOrTraitItemId> {
let cdata = cstore.get_crate_data(def.krate); 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, pub fn get_item_variances(cstore: &cstore::CStore,
def: DefId) -> ty::ItemVariances { def: DefId) -> ty::ItemVariances {
let cdata = cstore.get_crate_data(def.krate); 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>, pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
@ -161,43 +161,43 @@ pub fn get_provided_trait_methods<'tcx>(tcx: &ty::ctxt<'tcx>,
-> Vec<Rc<ty::Method<'tcx>>> { -> Vec<Rc<ty::Method<'tcx>>> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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) pub fn get_associated_consts<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
-> Vec<Rc<ty::AssociatedConst<'tcx>>> { -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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) pub fn get_type_name_if_impl(cstore: &cstore::CStore, def: DefId)
-> Option<ast::Name> { -> Option<ast::Name> {
let cdata = cstore.get_crate_data(def.krate); 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, pub fn get_methods_if_impl(cstore: &cstore::CStore,
def: DefId) def: DefId)
-> Option<Vec<MethodInfo> > { -> Option<Vec<MethodInfo> > {
let cdata = cstore.get_crate_data(def.krate); 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, pub fn get_item_attrs(cstore: &cstore::CStore,
def_id: DefId) def_id: DefId)
-> Vec<ast::Attribute> { -> Vec<ast::Attribute> {
let cdata = cstore.get_crate_data(def_id.krate); 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> { pub fn get_struct_field_names(cstore: &cstore::CStore, def: DefId) -> Vec<ast::Name> {
let cdata = cstore.get_crate_data(def.krate); 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, pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId)
Vec<ast::Attribute>> { -> FnvHashMap<DefId, Vec<ast::Attribute>> {
let cdata = cstore.get_crate_data(def.krate); let cdata = cstore.get_crate_data(def.krate);
decoder::get_struct_field_attrs(&*cdata) decoder::get_struct_field_attrs(&*cdata)
} }
@ -207,19 +207,19 @@ pub fn get_type<'tcx>(tcx: &ty::ctxt<'tcx>,
-> ty::TypeScheme<'tcx> { -> ty::TypeScheme<'tcx> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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> { pub fn get_trait_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::TraitDef<'tcx> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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> { pub fn get_adt_def<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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) pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@ -227,7 +227,7 @@ pub fn get_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
{ {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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) pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
@ -235,7 +235,7 @@ pub fn get_super_predicates<'tcx>(tcx: &ty::ctxt<'tcx>, def: DefId)
{ {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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>, pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
@ -244,7 +244,7 @@ pub fn get_impl_polarity<'tcx>(tcx: &ty::ctxt<'tcx>,
{ {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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>( pub fn get_custom_coerce_unsized_kind<'tcx>(
@ -254,7 +254,7 @@ pub fn get_custom_coerce_unsized_kind<'tcx>(
{ {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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, // Given a def_id for an impl, return the trait it implements,
@ -264,7 +264,7 @@ pub fn get_impl_trait<'tcx>(tcx: &ty::ctxt<'tcx>,
-> Option<ty::TraitRef<'tcx>> { -> Option<ty::TraitRef<'tcx>> {
let cstore = &tcx.sess.cstore; let cstore = &tcx.sess.cstore;
let cdata = cstore.get_crate_data(def.krate); 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) pub fn get_native_libraries(cstore: &cstore::CStore, crate_num: ast::CrateNum)
@ -279,7 +279,7 @@ pub fn each_inherent_implementation_for_type<F>(cstore: &cstore::CStore,
F: FnMut(DefId), F: FnMut(DefId),
{ {
let cdata = cstore.get_crate_data(def_id.krate); 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, pub fn each_implementation_for_trait<F>(cstore: &cstore::CStore,
@ -300,7 +300,7 @@ pub fn get_trait_of_item(cstore: &cstore::CStore,
tcx: &ty::ctxt) tcx: &ty::ctxt)
-> Option<DefId> { -> Option<DefId> {
let cdata = cstore.get_crate_data(def_id.krate); 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, pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
@ -308,7 +308,7 @@ pub fn get_tuple_struct_definition_if_ctor(cstore: &cstore::CStore,
-> Option<DefId> -> Option<DefId>
{ {
let cdata = cstore.get_crate_data(def_id.krate); 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, pub fn get_dylib_dependency_formats(cstore: &cstore::CStore,
@ -330,7 +330,7 @@ pub fn get_method_arg_names(cstore: &cstore::CStore, did: DefId)
-> Vec<String> -> Vec<String>
{ {
let cdata = cstore.get_crate_data(did.krate); 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 get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
@ -342,24 +342,24 @@ pub fn get_reachable_ids(cstore: &cstore::CStore, cnum: ast::CrateNum)
pub fn is_typedef(cstore: &cstore::CStore, did: DefId) -> bool { pub fn is_typedef(cstore: &cstore::CStore, did: DefId) -> bool {
let cdata = cstore.get_crate_data(did.krate); 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 { pub fn is_const_fn(cstore: &cstore::CStore, did: DefId) -> bool {
let cdata = cstore.get_crate_data(did.krate); 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 { pub fn is_impl(cstore: &cstore::CStore, did: DefId) -> bool {
let cdata = cstore.get_crate_data(did.krate); 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, pub fn get_stability(cstore: &cstore::CStore,
def: DefId) def: DefId)
-> Option<attr::Stability> { -> Option<attr::Stability> {
let cdata = cstore.get_crate_data(def.krate); 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 is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool {
@ -369,21 +369,42 @@ pub fn is_staged_api(cstore: &cstore::CStore, krate: ast::CrateNum) -> bool {
pub fn get_repr_attrs(cstore: &cstore::CStore, def: DefId) pub fn get_repr_attrs(cstore: &cstore::CStore, def: DefId)
-> Vec<attr::ReprAttr> { -> Vec<attr::ReprAttr> {
let cdata = cstore.get_crate_data(def.krate); 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 { pub fn is_defaulted_trait(cstore: &cstore::CStore, trait_def_id: DefId) -> bool {
let cdata = cstore.get_crate_data(trait_def_id.krate); 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 { pub fn is_default_impl(cstore: &cstore::CStore, impl_did: DefId) -> bool {
let cdata = cstore.get_crate_data(impl_did.krate); 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, pub fn is_extern_fn(cstore: &cstore::CStore, did: DefId,
tcx: &ty::ctxt) -> bool { tcx: &ty::ctxt) -> bool {
let cdata = cstore.get_crate_data(did.krate); 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()
}

View file

@ -59,6 +59,7 @@ pub struct ImportedFileMap {
pub struct crate_metadata { pub struct crate_metadata {
pub name: String, pub name: String,
pub local_path: RefCell<SmallVector<ast_map::PathElem>>, pub local_path: RefCell<SmallVector<ast_map::PathElem>>,
pub local_def_path: RefCell<ast_map::DefPath>,
pub data: MetadataBlob, pub data: MetadataBlob,
pub cnum_map: RefCell<cnum_map>, pub cnum_map: RefCell<cnum_map>,
pub cnum: ast::CrateNum, pub cnum: ast::CrateNum,
@ -312,6 +313,23 @@ impl crate_metadata {
} }
} }
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 { pub fn is_allocator(&self) -> bool {
let attrs = decoder::get_crate_attributes(self.data()); let attrs = decoder::get_crate_attributes(self.data());
attr::contains_name(&attrs, "allocator") attr::contains_name(&attrs, "allocator")

View file

@ -30,7 +30,7 @@ use metadata::index;
use metadata::inline::InlinedItem; use metadata::inline::InlinedItem;
use metadata::tydecode::TyDecoder; use metadata::tydecode::TyDecoder;
use middle::def; use middle::def;
use middle::def_id::DefId; use middle::def_id::{DefId, DefIndex};
use middle::lang_items; use middle::lang_items;
use middle::subst; use middle::subst;
use middle::ty::{ImplContainer, TraitContainer}; use middle::ty::{ImplContainer, TraitContainer};
@ -59,15 +59,15 @@ use syntax::ptr::P;
pub type Cmd<'a> = &'a crate_metadata; pub type Cmd<'a> = &'a crate_metadata;
impl 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| { self.index.lookup_item(self.data(), item_id).map(|pos| {
reader::doc_at(self.data(), pos as usize).unwrap().doc 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) { 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 Some(d) => d
} }
} }
@ -75,7 +75,7 @@ impl crate_metadata {
pub fn load_index(data: &[u8]) -> index::Index { pub fn load_index(data: &[u8]) -> index::Index {
let index = reader::get_doc(rbml::Doc::new(data), tag_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> { pub fn crate_rustc_version(data: &[u8]) -> Option<String> {
@ -170,7 +170,8 @@ fn item_symbol(item: rbml::Doc) -> String {
fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId { fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId {
let id = reader::doc_as_u64(d); 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) translate_def_id(cdata, def_id)
} }
@ -203,14 +204,14 @@ fn variant_disr_val(d: rbml::Doc) -> Option<ty::Disr> {
fn doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Ty<'tcx> { 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); let tp = reader::get_doc(doc, tag_items_data_item_type);
TyDecoder::with_doc(tcx, cdata.cnum, tp, TyDecoder::with_doc(tcx, cdata.cnum, tp,
&mut |_, did| translate_def_id(cdata, did)) &mut |did| translate_def_id(cdata, did))
.parse_ty() .parse_ty()
} }
fn maybe_doc_type<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) -> Option<Ty<'tcx>> { 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| { reader::maybe_get_doc(doc, tag_items_data_item_type).map(|tp| {
TyDecoder::with_doc(tcx, cdata.cnum, tp, TyDecoder::with_doc(tcx, cdata.cnum, tp,
&mut |_, did| translate_def_id(cdata, did)) &mut |did| translate_def_id(cdata, did))
.parse_ty() .parse_ty()
}) })
} }
@ -219,7 +220,7 @@ fn doc_method_fty<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>,
cdata: Cmd) -> ty::BareFnTy<'tcx> { cdata: Cmd) -> ty::BareFnTy<'tcx> {
let tp = reader::get_doc(doc, tag_item_method_fty); let tp = reader::get_doc(doc, tag_item_method_fty);
TyDecoder::with_doc(tcx, cdata.cnum, tp, 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() .parse_bare_fn_ty()
} }
@ -231,7 +232,7 @@ pub fn item_type<'tcx>(_item_id: DefId, item: rbml::Doc,
fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd) fn doc_trait_ref<'tcx>(doc: rbml::Doc, tcx: &ty::ctxt<'tcx>, cdata: Cmd)
-> ty::TraitRef<'tcx> { -> ty::TraitRef<'tcx> {
TyDecoder::with_doc(tcx, cdata.cnum, doc, TyDecoder::with_doc(tcx, cdata.cnum, doc,
&mut |_, did| translate_def_id(cdata, did)) &mut |did| translate_def_id(cdata, did))
.parse_trait_ref() .parse_trait_ref()
} }
@ -345,7 +346,7 @@ fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
} }
pub fn get_trait_def<'tcx>(cdata: Cmd, pub fn get_trait_def<'tcx>(cdata: Cmd,
item_id: ast::NodeId, item_id: DefIndex,
tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx> tcx: &ty::ctxt<'tcx>) -> ty::TraitDef<'tcx>
{ {
let item_doc = cdata.lookup_item(item_id); let item_doc = cdata.lookup_item(item_id);
@ -368,7 +369,7 @@ pub fn get_trait_def<'tcx>(cdata: Cmd,
pub fn get_adt_def<'tcx>(intr: &IdentInterner, pub fn get_adt_def<'tcx>(intr: &IdentInterner,
cdata: Cmd, cdata: Cmd,
item_id: ast::NodeId, item_id: DefIndex,
tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx> tcx: &ty::ctxt<'tcx>) -> ty::AdtDefMaster<'tcx>
{ {
fn get_enum_variants<'tcx>(intr: &IdentInterner, fn get_enum_variants<'tcx>(intr: &IdentInterner,
@ -378,7 +379,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
let mut disr_val = 0; let mut disr_val = 0;
reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| { reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| {
let did = translated_def_id(cdata, 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) { if let Some(disr) = variant_disr_val(item) {
disr_val = disr; disr_val = disr;
@ -428,7 +429,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
} }
let doc = cdata.lookup_item(item_id); 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) { let (kind, variants) = match item_family(doc) {
Enum => (ty::AdtKind::Enum, Enum => (ty::AdtKind::Enum,
get_enum_variants(intr, cdata, doc, tcx)), get_enum_variants(intr, cdata, doc, tcx)),
@ -448,7 +449,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
// from the ctor. // from the ctor.
debug!("evaluating the ctor-type of {:?}", debug!("evaluating the ctor-type of {:?}",
variant.name); 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 {:?}.. {:?}", debug!("evaluating the ctor-type of {:?}.. {:?}",
variant.name, variant.name,
ctor_ty); ctor_ty);
@ -468,7 +469,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
} else { } else {
for field in &variant.fields { for field in &variant.fields {
debug!("evaluating the type of {:?}::{:?}", variant.name, field.name); 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); field.fulfill_ty(ty);
debug!("evaluating the type of {:?}::{:?}: {:?}", debug!("evaluating the type of {:?}::{:?}: {:?}",
variant.name, field.name, ty); variant.name, field.name, ty);
@ -480,7 +481,7 @@ pub fn get_adt_def<'tcx>(intr: &IdentInterner,
} }
pub fn get_predicates<'tcx>(cdata: Cmd, pub fn get_predicates<'tcx>(cdata: Cmd,
item_id: ast::NodeId, item_id: DefIndex,
tcx: &ty::ctxt<'tcx>) tcx: &ty::ctxt<'tcx>)
-> ty::GenericPredicates<'tcx> -> ty::GenericPredicates<'tcx>
{ {
@ -489,7 +490,7 @@ pub fn get_predicates<'tcx>(cdata: Cmd,
} }
pub fn get_super_predicates<'tcx>(cdata: Cmd, pub fn get_super_predicates<'tcx>(cdata: Cmd,
item_id: ast::NodeId, item_id: DefIndex,
tcx: &ty::ctxt<'tcx>) tcx: &ty::ctxt<'tcx>)
-> ty::GenericPredicates<'tcx> -> ty::GenericPredicates<'tcx>
{ {
@ -497,11 +498,11 @@ pub fn get_super_predicates<'tcx>(cdata: Cmd,
doc_predicates(item_doc, tcx, cdata, tag_item_super_predicates) 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> -> ty::TypeScheme<'tcx>
{ {
let item_doc = cdata.lookup_item(id); 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); cdata);
let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics); let generics = doc_generics(item_doc, tcx, cdata, tag_item_generics);
ty::TypeScheme { ty::TypeScheme {
@ -510,7 +511,7 @@ pub fn get_type<'tcx>(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt<'tcx>)
} }
} }
pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> { pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option<attr::Stability> {
let item = cdata.lookup_item(id); let item = cdata.lookup_item(id);
reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| { reader::maybe_get_doc(item, tag_items_data_item_stability).map(|doc| {
let mut decoder = reader::Decoder::new(doc); let mut decoder = reader::Decoder::new(doc);
@ -518,7 +519,7 @@ pub fn get_stability(cdata: Cmd, id: ast::NodeId) -> Option<attr::Stability> {
}) })
} }
pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> { pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec<attr::ReprAttr> {
let item = cdata.lookup_item(id); let item = cdata.lookup_item(id);
match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| { match reader::maybe_get_doc(item, tag_items_data_item_repr).map(|doc| {
let mut decoder = reader::Decoder::new(doc); let mut decoder = reader::Decoder::new(doc);
@ -530,7 +531,7 @@ pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec<attr::ReprAttr> {
} }
pub fn get_impl_polarity<'tcx>(cdata: Cmd, pub fn get_impl_polarity<'tcx>(cdata: Cmd,
id: ast::NodeId) id: DefIndex)
-> Option<hir::ImplPolarity> -> Option<hir::ImplPolarity>
{ {
let item_doc = cdata.lookup_item(id); let item_doc = cdata.lookup_item(id);
@ -545,7 +546,7 @@ pub fn get_impl_polarity<'tcx>(cdata: Cmd,
pub fn get_custom_coerce_unsized_kind<'tcx>( pub fn get_custom_coerce_unsized_kind<'tcx>(
cdata: Cmd, cdata: Cmd,
id: ast::NodeId) id: DefIndex)
-> Option<ty::adjustment::CustomCoerceUnsized> -> Option<ty::adjustment::CustomCoerceUnsized>
{ {
let item_doc = cdata.lookup_item(id); let item_doc = cdata.lookup_item(id);
@ -556,7 +557,7 @@ pub fn get_custom_coerce_unsized_kind<'tcx>(
} }
pub fn get_impl_trait<'tcx>(cdata: Cmd, pub fn get_impl_trait<'tcx>(cdata: Cmd,
id: ast::NodeId, id: DefIndex,
tcx: &ty::ctxt<'tcx>) tcx: &ty::ctxt<'tcx>)
-> Option<ty::TraitRef<'tcx>> -> Option<ty::TraitRef<'tcx>>
{ {
@ -572,12 +573,12 @@ pub fn get_impl_trait<'tcx>(cdata: Cmd,
} }
} }
pub fn get_symbol(cdata: Cmd, id: ast::NodeId) -> String { pub fn get_symbol(cdata: Cmd, id: DefIndex) -> String {
return item_symbol(cdata.lookup_item(id)); return item_symbol(cdata.lookup_item(id));
} }
/// If you have a crate_metadata, call get_symbol instead /// 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 index = load_index(data);
let pos = index.lookup_item(data, id).unwrap(); let pos = index.lookup_item(data, id).unwrap();
let doc = reader::doc_at(data, pos as usize).unwrap().doc; let doc = reader::doc_at(data, pos as usize).unwrap().doc;
@ -594,18 +595,17 @@ pub enum DefLike {
/// Iterates over the language items in the given crate. /// Iterates over the language items in the given crate.
pub fn each_lang_item<F>(cdata: Cmd, mut f: F) -> bool where 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 root = rbml::Doc::new(cdata.data());
let lang_items = reader::get_doc(root, tag_lang_items); let lang_items = reader::get_doc(root, tag_lang_items);
reader::tagged_docs(lang_items, tag_lang_items_item).all(|item_doc| { 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_doc = reader::get_doc(item_doc, tag_lang_items_item_id);
let id = reader::doc_as_u32(id_doc) as usize; let id = reader::doc_as_u32(id_doc) as usize;
let node_id_doc = reader::get_doc(item_doc, let index_doc = reader::get_doc(item_doc, tag_lang_items_item_index);
tag_lang_items_item_node_id); let index = DefIndex::from_u32(reader::doc_as_u32(index_doc));
let node_id = reader::doc_as_u32(node_id_doc) as ast::NodeId;
f(node_id, id) f(index, id)
}) })
} }
@ -634,7 +634,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
}; };
// Get the item. // Get the item.
match crate_data.get_item(child_def_id.xxx_node) { match crate_data.get_item(child_def_id.index) {
None => {} None => {}
Some(child_item_doc) => { Some(child_item_doc) => {
// Hand off the item to the callback. // Hand off the item to the callback.
@ -652,12 +652,12 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
for inherent_impl_def_id_doc in reader::tagged_docs(item_doc, for inherent_impl_def_id_doc in reader::tagged_docs(item_doc,
tag_items_data_item_inherent_impl) { tag_items_data_item_inherent_impl) {
let inherent_impl_def_id = item_def_id(inherent_impl_def_id_doc, cdata); 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, for impl_item_def_id_doc in reader::tagged_docs(inherent_impl_doc,
tag_item_impl_item) { tag_item_impl_item) {
let impl_item_def_id = item_def_id(impl_item_def_id_doc, let impl_item_def_id = item_def_id(impl_item_def_id_doc,
cdata); 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) { if let StaticMethod = item_family(impl_method_doc) {
// Hand off the static method to the callback. // Hand off the static method to the callback.
let static_method_name = item_name(&*intr, impl_method_doc); let static_method_name = item_name(&*intr, impl_method_doc);
@ -693,7 +693,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
}; };
// Get the item. // 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. // Hand off the item to the callback.
let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id); 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 // These items have a public visibility because they're part of
@ -706,7 +706,7 @@ fn each_child_of_item_or_crate<F, G>(intr: Rc<IdentInterner>,
/// Iterates over each child of the given item. /// Iterates over each child of the given item.
pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>, pub fn each_child_of_item<F, G>(intr: Rc<IdentInterner>,
cdata: Cmd, cdata: Cmd,
id: ast::NodeId, id: DefIndex,
get_crate_data: G, get_crate_data: G,
callback: F) where callback: F) where
F: FnMut(DefLike, ast::Name, hir::Visibility), F: FnMut(DefLike, ast::Name, hir::Visibility),
@ -745,11 +745,11 @@ pub fn each_top_level_item_of_crate<F, G>(intr: Rc<IdentInterner>,
callback) 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)) 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)) item_name(intr, cdata.lookup_item(id))
} }
@ -757,22 +757,25 @@ pub type DecodeInlinedItem<'a> =
Box<for<'tcx> FnMut(Cmd, Box<for<'tcx> FnMut(Cmd,
&ty::ctxt<'tcx>, &ty::ctxt<'tcx>,
Vec<hir_map::PathElem>, Vec<hir_map::PathElem>,
hir_map::DefPath,
rbml::Doc) 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) mut decode_inlined_item: DecodeInlinedItem)
-> csearch::FoundAst<'tcx> { -> csearch::FoundAst<'tcx> {
debug!("Looking up item: {}", id); debug!("Looking up item: {:?}", id);
let item_doc = cdata.lookup_item(id); let item_doc = cdata.lookup_item(id);
let path = item_path(item_doc).split_last().unwrap().1.to_vec(); 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), Ok(ii) => csearch::FoundAst::Found(ii),
Err(path) => { Err((path, def_path)) => {
match item_parent_item(cdata, item_doc) { match item_parent_item(cdata, item_doc) {
Some(did) => { Some(did) => {
let parent_item = cdata.lookup_item(did.xxx_node); let parent_item = cdata.lookup_item(did.index);
match decode_inlined_item(cdata, tcx, path, parent_item) { match decode_inlined_item(cdata, tcx, path, def_path, parent_item) {
Ok(ii) => csearch::FoundAst::FoundParent(did, ii), Ok(ii) => csearch::FoundAst::FoundParent(did, ii),
Err(_) => csearch::FoundAst::NotFound Err(_) => csearch::FoundAst::NotFound
} }
@ -811,7 +814,7 @@ fn get_explicit_self(item: rbml::Doc) -> ty::ExplicitSelfCategory {
} }
/// Returns the def IDs of all the items in the given implementation. /// 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> { -> Vec<ty::ImplOrTraitItemId> {
reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| { reader::tagged_docs(cdata.lookup_item(impl_id), tag_item_impl_item).map(|doc| {
let def_id = item_def_id(doc, cdata); let def_id = item_def_id(doc, cdata);
@ -826,13 +829,13 @@ pub fn get_impl_items(cdata: Cmd, impl_id: ast::NodeId)
pub fn get_trait_name(intr: Rc<IdentInterner>, pub fn get_trait_name(intr: Rc<IdentInterner>,
cdata: Cmd, cdata: Cmd,
id: ast::NodeId) id: DefIndex)
-> ast::Name { -> ast::Name {
let doc = cdata.lookup_item(id); let doc = cdata.lookup_item(id);
item_name(&*intr, doc) 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); let doc = cdata.lookup_item(id);
match item_sort(doc) { match item_sort(doc) {
Some('r') | Some('p') => { Some('r') | Some('p') => {
@ -844,7 +847,7 @@ pub fn is_static_method(cdata: Cmd, id: ast::NodeId) -> bool {
pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>, pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
cdata: Cmd, cdata: Cmd,
id: ast::NodeId, id: DefIndex,
tcx: &ty::ctxt<'tcx>) tcx: &ty::ctxt<'tcx>)
-> ty::ImplOrTraitItem<'tcx> { -> ty::ImplOrTraitItem<'tcx> {
let item_doc = cdata.lookup_item(id); let item_doc = cdata.lookup_item(id);
@ -852,7 +855,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
let def_id = item_def_id(item_doc, cdata); let def_id = item_def_id(item_doc, cdata);
let container_id = item_require_parent_item(cdata, item_doc); 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) { let container = match item_family(container_doc) {
Trait => TraitContainer(container_id), Trait => TraitContainer(container_id),
_ => ImplContainer(container_id), _ => ImplContainer(container_id),
@ -902,7 +905,7 @@ pub fn get_impl_or_trait_item<'tcx>(intr: Rc<IdentInterner>,
} }
} }
pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId) pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex)
-> Vec<ty::ImplOrTraitItemId> { -> Vec<ty::ImplOrTraitItemId> {
let item = cdata.lookup_item(id); let item = cdata.lookup_item(id);
reader::tagged_docs(item, tag_item_trait_item).map(|mth| { reader::tagged_docs(item, tag_item_trait_item).map(|mth| {
@ -916,7 +919,7 @@ pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId)
}).collect() }).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 item_doc = cdata.lookup_item(id);
let variance_doc = reader::get_doc(item_doc, tag_item_variances); let variance_doc = reader::get_doc(item_doc, tag_item_variances);
let mut decoder = reader::Decoder::new(variance_doc); let mut decoder = reader::Decoder::new(variance_doc);
@ -925,19 +928,19 @@ pub fn get_item_variances(cdata: Cmd, id: ast::NodeId) -> ty::ItemVariances {
pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>, pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
cdata: Cmd, cdata: Cmd,
id: ast::NodeId, id: DefIndex,
tcx: &ty::ctxt<'tcx>) tcx: &ty::ctxt<'tcx>)
-> Vec<Rc<ty::Method<'tcx>>> { -> Vec<Rc<ty::Method<'tcx>>> {
let item = cdata.lookup_item(id); let item = cdata.lookup_item(id);
reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| { reader::tagged_docs(item, tag_item_trait_item).filter_map(|mth_id| {
let did = item_def_id(mth_id, cdata); 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') { if item_sort(mth) == Some('p') {
let trait_item = get_impl_or_trait_item(intr.clone(), let trait_item = get_impl_or_trait_item(intr.clone(),
cdata, cdata,
did.xxx_node, did.index,
tcx); tcx);
if let ty::MethodTraitItem(ref method) = trait_item { if let ty::MethodTraitItem(ref method) = trait_item {
Some((*method).clone()) Some((*method).clone())
@ -952,7 +955,7 @@ pub fn get_provided_trait_methods<'tcx>(intr: Rc<IdentInterner>,
pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>, pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
cdata: Cmd, cdata: Cmd,
id: ast::NodeId, id: DefIndex,
tcx: &ty::ctxt<'tcx>) tcx: &ty::ctxt<'tcx>)
-> Vec<Rc<ty::AssociatedConst<'tcx>>> { -> Vec<Rc<ty::AssociatedConst<'tcx>>> {
let item = cdata.lookup_item(id); let item = cdata.lookup_item(id);
@ -960,13 +963,13 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
[tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| { [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| {
reader::tagged_docs(item, tag).filter_map(|ac_id| { reader::tagged_docs(item, tag).filter_map(|ac_id| {
let did = item_def_id(ac_id, cdata); 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) { match item_sort(ac_doc) {
Some('C') | Some('c') => { Some('C') | Some('c') => {
let trait_item = get_impl_or_trait_item(intr.clone(), let trait_item = get_impl_or_trait_item(intr.clone(),
cdata, cdata,
did.xxx_node, did.index,
tcx); tcx);
if let ty::ConstTraitItem(ref ac) = trait_item { if let ty::ConstTraitItem(ref ac) = trait_item {
Some((*ac).clone()) Some((*ac).clone())
@ -981,7 +984,7 @@ pub fn get_associated_consts<'tcx>(intr: Rc<IdentInterner>,
} }
pub fn get_type_name_if_impl(cdata: Cmd, 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); let item = cdata.lookup_item(node_id);
if item_family(item) != Impl { if item_family(item) != Impl {
return None; return None;
@ -994,7 +997,7 @@ pub fn get_type_name_if_impl(cdata: Cmd,
pub fn get_methods_if_impl(intr: Rc<IdentInterner>, pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
cdata: Cmd, cdata: Cmd,
node_id: ast::NodeId) node_id: DefIndex)
-> Option<Vec<MethodInfo> > { -> Option<Vec<MethodInfo> > {
let item = cdata.lookup_item(node_id); let item = cdata.lookup_item(node_id);
if item_family(item) != Impl { if item_family(item) != Impl {
@ -1011,7 +1014,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
let mut impl_methods = Vec::new(); let mut impl_methods = Vec::new();
for impl_method_id in impl_method_ids { 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); let family = item_family(impl_method_doc);
match family { match family {
StaticMethod | Method => { StaticMethod | Method => {
@ -1031,7 +1034,7 @@ pub fn get_methods_if_impl(intr: Rc<IdentInterner>,
/// If node_id is the constructor of a tuple struct, retrieve the NodeId of /// If node_id is the constructor of a tuple struct, retrieve the NodeId of
/// the actual type definition, otherwise, return None /// the actual type definition, otherwise, return None
pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
node_id: ast::NodeId) node_id: DefIndex)
-> Option<DefId> -> Option<DefId>
{ {
let item = cdata.lookup_item(node_id); let item = cdata.lookup_item(node_id);
@ -1041,24 +1044,24 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd,
} }
pub fn get_item_attrs(cdata: Cmd, pub fn get_item_attrs(cdata: Cmd,
orig_node_id: ast::NodeId) orig_node_id: DefIndex)
-> Vec<ast::Attribute> { -> Vec<ast::Attribute> {
// The attributes for a tuple struct are attached to the definition, not the ctor; // 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 // we assume that someone passing in a tuple struct ctor is actually wanting to
// look at the definition // look at the definition
let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id); 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); let item = cdata.lookup_item(node_id);
get_attributes(item) 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 data = rbml::Doc::new(cdata.data());
let fields = reader::get_doc(data, tag_struct_fields); let fields = reader::get_doc(data, tag_struct_fields);
reader::tagged_docs(fields, tag_struct_field).map(|field| { 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); let attrs = get_attributes(field);
(id, attrs) (def_id, attrs)
}).collect() }).collect()
} }
@ -1070,7 +1073,7 @@ fn struct_field_family_to_visibility(family: Family) -> hir::Visibility {
} }
} }
pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: ast::NodeId) pub fn get_struct_field_names(intr: &IdentInterner, cdata: Cmd, id: DefIndex)
-> Vec<ast::Name> { -> Vec<ast::Name> {
let item = cdata.lookup_item(id); let item = cdata.lookup_item(id);
reader::tagged_docs(item, tag_item_field).map(|an_item| { reader::tagged_docs(item, tag_item_field).map(|an_item| {
@ -1228,14 +1231,14 @@ pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()>
// crate to the correct local crate number. // crate to the correct local crate number.
pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId { pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
if did.is_local() { 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) { match cdata.cnum_map.borrow().get(&did.krate) {
Some(&n) => { Some(&n) => {
DefId { DefId {
krate: n, krate: n,
xxx_node: did.xxx_node, index: did.index,
} }
} }
None => panic!("didn't find a crate in the cnum_map") None => panic!("didn't find a crate in the cnum_map")
@ -1246,12 +1249,12 @@ pub fn translate_def_id(cdata: Cmd, did: DefId) -> DefId {
// for an external crate. // for an external crate.
fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> { fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
if did.krate == cdata.cnum { 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() { for (&local, &global) in cdata.cnum_map.borrow().iter() {
if global == did.krate { if global == did.krate {
return Some(DefId { krate: local, xxx_node: did.xxx_node }); return Some(DefId { krate: local, index: did.index });
} }
} }
@ -1259,7 +1262,7 @@ fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option<DefId> {
} }
pub fn each_inherent_implementation_for_type<F>(cdata: Cmd, pub fn each_inherent_implementation_for_type<F>(cdata: Cmd,
id: ast::NodeId, id: DefIndex,
mut callback: F) mut callback: F)
where F: FnMut(DefId), where F: FnMut(DefId),
{ {
@ -1277,7 +1280,7 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
F: FnMut(DefId), F: FnMut(DefId),
{ {
if cdata.cnum == def_id.krate { 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) { for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_extension_impl) {
callback(item_def_id(impl_doc, cdata)); callback(item_def_id(impl_doc, cdata));
} }
@ -1299,14 +1302,14 @@ pub fn each_implementation_for_trait<F>(cdata: Cmd,
} }
} }
pub fn get_trait_of_item(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) pub fn get_trait_of_item(cdata: Cmd, id: DefIndex, tcx: &ty::ctxt)
-> Option<DefId> { -> Option<DefId> {
let item_doc = cdata.lookup_item(id); let item_doc = cdata.lookup_item(id);
let parent_item_id = match item_parent_item(cdata, item_doc) { let parent_item_id = match item_parent_item(cdata, item_doc) {
None => return None, None => return None,
Some(item_id) => item_id, 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) { match item_family(parent_item_doc) {
Trait => Some(item_def_id(parent_item_doc, cdata)), Trait => Some(item_def_id(parent_item_doc, cdata)),
Impl | DefaultImpl => { Impl | DefaultImpl => {
@ -1332,9 +1335,9 @@ pub fn get_native_libraries(cdata: Cmd)
}).collect() }).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) 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 pub fn each_exported_macro<F>(data: &[u8], intr: &IdentInterner, mut f: F) where
@ -1386,7 +1389,7 @@ pub fn get_missing_lang_items(cdata: Cmd)
}).collect() }).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); let method_doc = cdata.lookup_item(id);
match reader::maybe_get_doc(method_doc, tag_method_argument_names) { match reader::maybe_get_doc(method_doc, tag_method_argument_names) {
Some(args_doc) => { Some(args_doc) => {
@ -1404,12 +1407,12 @@ pub fn get_reachable_ids(cdata: Cmd) -> Vec<DefId> {
reader::tagged_docs(items, tag_reachable_id).map(|doc| { reader::tagged_docs(items, tag_reachable_id).map(|doc| {
DefId { DefId {
krate: cdata.cnum, krate: cdata.cnum,
xxx_node: reader::doc_as_u32(doc), index: DefIndex::from_u32(reader::doc_as_u32(doc)),
} }
}).collect() }).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); let item_doc = cdata.lookup_item(id);
match item_family(item_doc) { match item_family(item_doc) {
Type => true, Type => true,
@ -1417,7 +1420,7 @@ pub fn is_typedef(cdata: Cmd, id: ast::NodeId) -> bool {
} }
} }
pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool { pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool {
let item_doc = cdata.lookup_item(id); let item_doc = cdata.lookup_item(id);
match fn_constness(item_doc) { match fn_constness(item_doc) {
hir::Constness::Const => true, hir::Constness::Const => true,
@ -1425,7 +1428,7 @@ pub fn is_const_fn(cdata: Cmd, id: ast::NodeId) -> bool {
} }
} }
pub fn is_impl(cdata: Cmd, id: ast::NodeId) -> bool { pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool {
let item_doc = cdata.lookup_item(id); let item_doc = cdata.lookup_item(id);
match item_family(item_doc) { match item_family(item_doc) {
Impl => true, Impl => true,
@ -1445,7 +1448,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
for p in reader::tagged_docs(doc, tag_type_param_def) { for p in reader::tagged_docs(doc, tag_type_param_def) {
let bd = let bd =
TyDecoder::with_doc(tcx, cdata.cnum, p, 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(); .parse_type_param_def();
types.push(bd.space, bd); types.push(bd.space, bd);
} }
@ -1467,7 +1470,7 @@ fn doc_generics<'tcx>(base_doc: rbml::Doc,
let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| { let bounds = reader::tagged_docs(rp_doc, tag_items_data_region).map(|p| {
TyDecoder::with_doc(tcx, cdata.cnum, p, TyDecoder::with_doc(tcx, cdata.cnum, p,
&mut |_, did| translate_def_id(cdata, did)) &mut |did| translate_def_id(cdata, did))
.parse_region() .parse_region()
}).collect(); }).collect();
@ -1497,7 +1500,7 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc,
let data_doc = reader::get_doc(predicate_doc, tag_predicate_data); let data_doc = reader::get_doc(predicate_doc, tag_predicate_data);
let data = let data =
TyDecoder::with_doc(tcx, cdata.cnum, data_doc, TyDecoder::with_doc(tcx, cdata.cnum, data_doc,
&mut |_, did| translate_def_id(cdata, did)) &mut |did| translate_def_id(cdata, did))
.parse_predicate(); .parse_predicate();
predicates.push(space, data); predicates.push(space, data);
@ -1506,14 +1509,14 @@ fn doc_predicates<'tcx>(base_doc: rbml::Doc,
ty::GenericPredicates { predicates: predicates } 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); let trait_doc = cdata.lookup_item(trait_id);
assert!(item_family(trait_doc) == Family::Trait); assert!(item_family(trait_doc) == Family::Trait);
let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait); let defaulted_doc = reader::get_doc(trait_doc, tag_defaulted_trait);
reader::doc_as_u8(defaulted_doc) != 0 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); let impl_doc = cdata.lookup_item(impl_id);
item_family(impl_doc) == Family::DefaultImpl item_family(impl_doc) == Family::DefaultImpl
} }
@ -1528,7 +1531,7 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec<codemap::FileMap> {
}).collect() }).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) { let item_doc = match cdata.get_item(id) {
Some(doc) => doc, Some(doc) => doc,
None => return false, None => return false,
@ -1543,3 +1546,42 @@ pub fn is_extern_fn(cdata: Cmd, id: ast::NodeId, tcx: &ty::ctxt) -> bool {
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)
})
}

View file

@ -20,10 +20,10 @@ use metadata::cstore;
use metadata::cstore::LOCAL_CRATE; use metadata::cstore::LOCAL_CRATE;
use metadata::decoder; use metadata::decoder;
use metadata::tyencode; use metadata::tyencode;
use metadata::index::{self, IndexEntry}; use metadata::index::IndexData;
use metadata::inline::InlinedItemRef; use metadata::inline::InlinedItemRef;
use middle::def; use middle::def;
use middle::def_id::DefId; use middle::def_id::{CRATE_DEF_INDEX, DefId};
use middle::dependency_format::Linkage; use middle::dependency_format::Linkage;
use middle::stability; use middle::stability;
use middle::ty::{self, Ty}; use middle::ty::{self, Ty};
@ -34,6 +34,7 @@ use std::cell::RefCell;
use std::io::prelude::*; use std::io::prelude::*;
use std::io::{Cursor, SeekFrom}; use std::io::{Cursor, SeekFrom};
use std::rc::Rc; use std::rc::Rc;
use std::u32;
use syntax::abi; use syntax::abi;
use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum}; use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID, CrateNum};
use syntax::attr; use syntax::attr;
@ -93,6 +94,26 @@ fn encode_def_id(rbml_w: &mut Encoder, id: DefId) {
rbml_w.wr_tagged_u64(tag_def_id, def_to_u64(id)); 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, fn encode_trait_ref<'a, 'tcx>(rbml_w: &mut Encoder,
ecx: &EncodeContext<'a, 'tcx>, ecx: &EncodeContext<'a, 'tcx>,
trait_ref: ty::TraitRef<'tcx>, trait_ref: ty::TraitRef<'tcx>,
@ -115,11 +136,12 @@ fn encode_family(rbml_w: &mut Encoder, c: char) {
} }
pub fn def_to_u64(did: DefId) -> u64 { 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 { 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, fn encode_item_variances(rbml_w: &mut Encoder,
@ -280,7 +302,7 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
id: NodeId, id: NodeId,
vis: hir::Visibility, vis: hir::Visibility,
index: &mut Vec<IndexEntry>) { index: &mut IndexData) {
debug!("encode_enum_variant_info(id={})", id); debug!("encode_enum_variant_info(id={})", id);
let mut disr_val = 0; let mut disr_val = 0;
@ -297,12 +319,9 @@ fn encode_enum_variant_info(ecx: &EncodeContext,
} }
} }
index.push(IndexEntry { index.record(vid, rbml_w);
node: vid.xxx_node,
pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item); 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() { encode_family(rbml_w, match variant.kind() {
ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v', ty::VariantKind::Unit | ty::VariantKind::Tuple => 'v',
ty::VariantKind::Dict => 'V' ty::VariantKind::Dict => 'V'
@ -522,7 +541,7 @@ fn encode_info_for_mod(ecx: &EncodeContext,
name: Name, name: Name,
vis: hir::Visibility) { vis: hir::Visibility) {
rbml_w.start_tag(tag_items_data_item); 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_family(rbml_w, 'm');
encode_name(rbml_w, name); encode_name(rbml_w, name);
debug!("(encoding info for module) encoding info for module ID {}", id); debug!("(encoding info for module) encoding info for module ID {}", id);
@ -631,21 +650,17 @@ fn encode_parent_sort(rbml_w: &mut Encoder, sort: char) {
fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_field<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
field: ty::FieldDef<'tcx>, field: ty::FieldDef<'tcx>,
global_index: &mut Vec<IndexEntry>) { global_index: &mut IndexData) {
let nm = field.name; let nm = field.name;
let id = ecx.local_id(field.did); let id = ecx.local_id(field.did);
let pos = rbml_w.mark_stable_position(); global_index.record(field.did, rbml_w);
global_index.push(IndexEntry {
node: id,
pos: pos,
});
rbml_w.start_tag(tag_items_data_item); rbml_w.start_tag(tag_items_data_item);
debug!("encode_field: encoding {} {}", nm, id); debug!("encode_field: encoding {} {}", nm, id);
encode_struct_field_family(rbml_w, field.vis); encode_struct_field_family(rbml_w, field.vis);
encode_name(rbml_w, nm); encode_name(rbml_w, nm);
encode_bounds_and_type_for_item(rbml_w, ecx, id); 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); let stab = stability::lookup(ecx.tcx, field.did);
encode_stability(rbml_w, stab); encode_stability(rbml_w, stab);
@ -657,15 +672,14 @@ fn encode_info_for_struct_ctor(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
name: Name, name: Name,
ctor_id: NodeId, ctor_id: NodeId,
index: &mut Vec<IndexEntry>, index: &mut IndexData,
struct_id: NodeId) { struct_id: NodeId) {
index.push(IndexEntry { let ctor_def_id = ecx.tcx.map.local_def_id(ctor_id);
node: ctor_id,
pos: rbml_w.mark_stable_position(), index.record(ctor_def_id, rbml_w);
});
rbml_w.start_tag(tag_items_data_item); 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_family(rbml_w, 'o');
encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id); encode_bounds_and_type_for_item(rbml_w, ecx, ctor_id);
encode_name(rbml_w, name); encode_name(rbml_w, name);
@ -775,7 +789,7 @@ fn encode_predicates<'a,'tcx>(rbml_w: &mut Encoder,
fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>, fn encode_method_ty_fields<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
method_ty: &ty::Method<'tcx>) { 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_name(rbml_w, method_ty.name);
encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates, encode_generics(rbml_w, ecx, &method_ty.generics, &method_ty.predicates,
tag_method_ty_generics); tag_method_ty_generics);
@ -802,7 +816,7 @@ fn encode_info_for_associated_const(ecx: &EncodeContext,
rbml_w.start_tag(tag_items_data_item); 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_name(rbml_w, associated_const.name);
encode_visibility(rbml_w, associated_const.vis); encode_visibility(rbml_w, associated_const.vis);
encode_family(rbml_w, 'C'); encode_family(rbml_w, 'C');
@ -891,7 +905,7 @@ fn encode_info_for_associated_type<'a, 'tcx>(ecx: &EncodeContext<'a, 'tcx>,
rbml_w.start_tag(tag_items_data_item); 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_name(rbml_w, associated_type.name);
encode_visibility(rbml_w, associated_type.vis); encode_visibility(rbml_w, associated_type.vis);
encode_family(rbml_w, 'y'); encode_family(rbml_w, 'y');
@ -1000,19 +1014,11 @@ fn encode_stability(rbml_w: &mut Encoder, stab_opt: Option<&attr::Stability>) {
fn encode_info_for_item(ecx: &EncodeContext, fn encode_info_for_item(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
item: &hir::Item, item: &hir::Item,
index: &mut Vec<IndexEntry>, index: &mut IndexData,
path: PathElems, path: PathElems,
vis: hir::Visibility) { vis: hir::Visibility) {
let tcx = ecx.tcx; 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 {}", debug!("encoding info for item at {}",
tcx.sess.codemap().span_to_string(item.span)); tcx.sess.codemap().span_to_string(item.span));
@ -1021,9 +1027,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
match item.node { match item.node {
hir::ItemStatic(_, m, _) => { hir::ItemStatic(_, m, _) => {
add_to_index(item, rbml_w, index); index.record(def_id, rbml_w);
rbml_w.start_tag(tag_items_data_item); 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 { if m == hir::MutMutable {
encode_family(rbml_w, 'b'); encode_family(rbml_w, 'b');
} else { } else {
@ -1039,9 +1045,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
rbml_w.end_tag(); rbml_w.end_tag();
} }
hir::ItemConst(_, _) => { hir::ItemConst(_, _) => {
add_to_index(item, rbml_w, index); index.record(def_id, rbml_w);
rbml_w.start_tag(tag_items_data_item); 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_family(rbml_w, 'C');
encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
encode_name(rbml_w, item.name); encode_name(rbml_w, item.name);
@ -1053,9 +1059,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
rbml_w.end_tag(); rbml_w.end_tag();
} }
hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { 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); 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); encode_family(rbml_w, FN_FAMILY);
let tps_len = generics.ty_params.len(); let tps_len = generics.ty_params.len();
encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
@ -1076,7 +1082,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
rbml_w.end_tag(); rbml_w.end_tag();
} }
hir::ItemMod(ref m) => { hir::ItemMod(ref m) => {
add_to_index(item, rbml_w, index); index.record(def_id, rbml_w);
encode_info_for_mod(ecx, encode_info_for_mod(ecx,
rbml_w, rbml_w,
m, m,
@ -1087,9 +1093,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
item.vis); item.vis);
} }
hir::ItemForeignMod(ref fm) => { 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); 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_family(rbml_w, 'n');
encode_name(rbml_w, item.name); encode_name(rbml_w, item.name);
encode_path(rbml_w, path); encode_path(rbml_w, path);
@ -1104,9 +1110,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
rbml_w.end_tag(); rbml_w.end_tag();
} }
hir::ItemTy(..) => { hir::ItemTy(..) => {
add_to_index(item, rbml_w, index); index.record(def_id, rbml_w);
rbml_w.start_tag(tag_items_data_item); 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_family(rbml_w, 'y');
encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
encode_name(rbml_w, item.name); encode_name(rbml_w, item.name);
@ -1116,10 +1122,10 @@ fn encode_info_for_item(ecx: &EncodeContext,
rbml_w.end_tag(); rbml_w.end_tag();
} }
hir::ItemEnum(ref enum_definition, _) => { 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); 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_family(rbml_w, 't');
encode_item_variances(rbml_w, ecx, item.id); encode_item_variances(rbml_w, ecx, item.id);
encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
@ -1154,11 +1160,11 @@ fn encode_info_for_item(ecx: &EncodeContext,
} }
/* Index the class*/ /* Index the class*/
add_to_index(item, rbml_w, index); index.record(def_id, rbml_w);
/* Now, make an item for the class itself */ /* Now, make an item for the class itself */
rbml_w.start_tag(tag_items_data_item); 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_family(rbml_w, 'S');
encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
@ -1192,9 +1198,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
} }
} }
hir::ItemDefaultImpl(unsafety, _) => { hir::ItemDefaultImpl(unsafety, _) => {
add_to_index(item, rbml_w, index); index.record(def_id, rbml_w);
rbml_w.start_tag(tag_items_data_item); 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_family(rbml_w, 'd');
encode_name(rbml_w, item.name); encode_name(rbml_w, item.name);
encode_unsafety(rbml_w, unsafety); encode_unsafety(rbml_w, unsafety);
@ -1209,9 +1215,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
let impl_items = tcx.impl_items.borrow(); let impl_items = tcx.impl_items.borrow();
let items = impl_items.get(&def_id).unwrap(); 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); 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_family(rbml_w, 'i');
encode_bounds_and_type_for_item(rbml_w, ecx, item.id); encode_bounds_and_type_for_item(rbml_w, ecx, item.id);
encode_name(rbml_w, item.name); encode_name(rbml_w, item.name);
@ -1272,10 +1278,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
None None
}; };
index.push(IndexEntry { index.record(trait_item_def_id.def_id(), rbml_w);
node: trait_item_def_id.def_id().xxx_node,
pos: rbml_w.mark_stable_position(),
});
match tcx.impl_or_trait_item(trait_item_def_id.def_id()) { match tcx.impl_or_trait_item(trait_item_def_id.def_id()) {
ty::ConstTraitItem(ref associated_const) => { ty::ConstTraitItem(ref associated_const) => {
@ -1307,9 +1310,9 @@ fn encode_info_for_item(ecx: &EncodeContext,
} }
} }
hir::ItemTrait(_, _, _, ref ms) => { 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); 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_family(rbml_w, 'I');
encode_item_variances(rbml_w, ecx, item.id); encode_item_variances(rbml_w, ecx, item.id);
let trait_def = tcx.lookup_trait_def(def_id); let trait_def = tcx.lookup_trait_def(def_id);
@ -1363,10 +1366,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
for (i, &item_def_id) in r.iter().enumerate() { for (i, &item_def_id) in r.iter().enumerate() {
assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE); assert_eq!(item_def_id.def_id().krate, LOCAL_CRATE);
index.push(IndexEntry { index.record(item_def_id.def_id(), rbml_w);
node: item_def_id.def_id().xxx_node,
pos: rbml_w.mark_stable_position(),
});
rbml_w.start_tag(tag_items_data_item); rbml_w.start_tag(tag_items_data_item);
@ -1381,7 +1381,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
match trait_item_type { match trait_item_type {
ty::ConstTraitItem(associated_const) => { ty::ConstTraitItem(associated_const) => {
encode_name(rbml_w, associated_const.name); 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); encode_visibility(rbml_w, associated_const.vis);
let elem = ast_map::PathName(associated_const.name); let elem = ast_map::PathName(associated_const.name);
@ -1422,7 +1422,7 @@ fn encode_info_for_item(ecx: &EncodeContext,
} }
ty::TypeTraitItem(associated_type) => { ty::TypeTraitItem(associated_type) => {
encode_name(rbml_w, associated_type.name); 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); let elem = ast_map::PathName(associated_type.name);
encode_path(rbml_w, encode_path(rbml_w,
@ -1491,16 +1491,15 @@ fn encode_info_for_item(ecx: &EncodeContext,
fn encode_info_for_foreign_item(ecx: &EncodeContext, fn encode_info_for_foreign_item(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
nitem: &hir::ForeignItem, nitem: &hir::ForeignItem,
index: &mut Vec<IndexEntry>, index: &mut IndexData,
path: PathElems, path: PathElems,
abi: abi::Abi) { abi: abi::Abi) {
index.push(IndexEntry { let def_id = ecx.tcx.map.local_def_id(nitem.id);
node: nitem.id,
pos: rbml_w.mark_stable_position(), index.record(def_id, rbml_w);
});
rbml_w.start_tag(tag_items_data_item); 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); encode_visibility(rbml_w, nitem.vis);
match nitem.node { match nitem.node {
hir::ForeignItemFn(ref fndecl, _) => { hir::ForeignItemFn(ref fndecl, _) => {
@ -1534,12 +1533,39 @@ fn encode_info_for_foreign_item(ecx: &EncodeContext,
rbml_w.end_tag(); 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, fn my_visit_item(i: &hir::Item,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
ecx: &EncodeContext, ecx: &EncodeContext,
index: &mut Vec<IndexEntry>) { index: &mut IndexData) {
ecx.tcx.map.with_path(i.id, |path| { ecx.tcx.map.with_path(i.id, |path| {
encode_info_for_item(ecx, rbml_w, i, index, path, i.vis); encode_info_for_item(ecx, rbml_w, i, index, path, i.vis);
}); });
@ -1548,7 +1574,7 @@ fn my_visit_item(i: &hir::Item,
fn my_visit_foreign_item(ni: &hir::ForeignItem, fn my_visit_foreign_item(ni: &hir::ForeignItem,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
ecx: &EncodeContext, ecx: &EncodeContext,
index: &mut Vec<IndexEntry>) { index: &mut IndexData) {
debug!("writing foreign item {}::{}", debug!("writing foreign item {}::{}",
ecx.tcx.map.path_to_string(ni.id), ecx.tcx.map.path_to_string(ni.id),
ni.name); ni.name);
@ -1564,40 +1590,32 @@ fn my_visit_foreign_item(ni: &hir::ForeignItem,
struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> { struct EncodeVisitor<'a, 'b:'a, 'c:'a, 'tcx:'c> {
rbml_w_for_visit_item: &'a mut Encoder<'b>, rbml_w_for_visit_item: &'a mut Encoder<'b>,
ecx: &'a EncodeContext<'c,'tcx>, 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> { impl<'a, 'b, 'c, 'tcx, 'v> Visitor<'v> for EncodeVisitor<'a, 'b, 'c, 'tcx> {
fn visit_expr(&mut self, ex: &hir::Expr) { fn visit_expr(&mut self, ex: &hir::Expr) {
visit::walk_expr(self, ex); 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) { fn visit_item(&mut self, i: &hir::Item) {
visit::walk_item(self, i); visit::walk_item(self, i);
my_visit_item(i, my_visit_item(i, self.rbml_w_for_visit_item, self.ecx, self.index);
self.rbml_w_for_visit_item,
self.ecx,
self.index);
} }
fn visit_foreign_item(&mut self, ni: &hir::ForeignItem) { fn visit_foreign_item(&mut self, ni: &hir::ForeignItem) {
visit::walk_foreign_item(self, ni); visit::walk_foreign_item(self, ni);
my_visit_foreign_item(ni, my_visit_foreign_item(ni, self.rbml_w_for_visit_item, self.ecx, self.index);
self.rbml_w_for_visit_item,
self.ecx,
self.index);
} }
} }
fn encode_info_for_items(ecx: &EncodeContext, fn encode_info_for_items(ecx: &EncodeContext,
rbml_w: &mut Encoder, rbml_w: &mut Encoder,
krate: &hir::Crate) krate: &hir::Crate)
-> Vec<IndexEntry> { -> IndexData {
let mut index = Vec::new(); let mut index = IndexData::new(ecx.tcx.map.num_local_def_ids());
rbml_w.start_tag(tag_items_data); rbml_w.start_tag(tag_items_data);
index.push(IndexEntry { index.record_index(CRATE_DEF_INDEX, rbml_w);
node: CRATE_NODE_ID,
pos: rbml_w.mark_stable_position(),
});
encode_info_for_mod(ecx, encode_info_for_mod(ecx,
rbml_w, rbml_w,
&krate.module, &krate.module,
@ -1617,13 +1635,9 @@ fn encode_info_for_items(ecx: &EncodeContext,
index index
} }
fn encode_index(rbml_w: &mut Encoder, index: IndexData) {
fn encode_index(rbml_w: &mut Encoder, index: Vec<IndexEntry>)
{
rbml_w.start_tag(tag_index); rbml_w.start_tag(tag_index);
index::write_index(index, rbml_w.writer); index.write_index(rbml_w.writer);
rbml_w.end_tag(); rbml_w.end_tag();
} }
@ -1737,12 +1751,12 @@ fn encode_crate_deps(rbml_w: &mut Encoder, cstore: &cstore::CStore) {
fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) { fn encode_lang_items(ecx: &EncodeContext, rbml_w: &mut Encoder) {
rbml_w.start_tag(tag_lang_items); rbml_w.start_tag(tag_lang_items);
for (i, &def_id) in ecx.tcx.lang_items.items() { for (i, &opt_def_id) in ecx.tcx.lang_items.items() {
if let Some(id) = def_id { if let Some(def_id) = opt_def_id {
if let Some(id) = ecx.tcx.map.as_local_node_id(id) { if def_id.is_local() {
rbml_w.start_tag(tag_lang_items_item); 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_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(); rbml_w.end_tag();
} }
} }
@ -1776,7 +1790,10 @@ fn encode_native_libraries(ecx: &EncodeContext, rbml_w: &mut Encoder) {
fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) { fn encode_plugin_registrar_fn(ecx: &EncodeContext, rbml_w: &mut Encoder) {
match ecx.tcx.sess.plugin_registrar_fn.get() { 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 => {} None => {}
} }
} }
@ -1821,24 +1838,26 @@ fn encode_macro_defs(rbml_w: &mut Encoder,
rbml_w.end_tag(); rbml_w.end_tag();
} }
fn encode_struct_field_attrs(rbml_w: &mut Encoder, krate: &hir::Crate) { fn encode_struct_field_attrs(ecx: &EncodeContext,
struct StructFieldVisitor<'a, 'b:'a> { rbml_w: &mut Encoder,
rbml_w: &'a mut Encoder<'b>, 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) { fn visit_struct_field(&mut self, field: &hir::StructField) {
self.rbml_w.start_tag(tag_struct_field); 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); encode_attributes(self.rbml_w, &field.node.attrs);
self.rbml_w.end_tag(); self.rbml_w.end_tag();
} }
} }
rbml_w.start_tag(tag_struct_fields); rbml_w.start_tag(tag_struct_fields);
visit::walk_crate(&mut StructFieldVisitor { visit::walk_crate(&mut StructFieldVisitor { ecx: ecx, rbml_w: rbml_w }, krate);
rbml_w: rbml_w
}, krate);
rbml_w.end_tag(); rbml_w.end_tag();
} }
@ -1925,8 +1944,9 @@ fn encode_misc_info(ecx: &EncodeContext,
// definition (as that's not defined in this crate). // definition (as that's not defined in this crate).
fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) { fn encode_reachable(ecx: &EncodeContext, rbml_w: &mut Encoder) {
rbml_w.start_tag(tag_reachable_ids); rbml_w.start_tag(tag_reachable_ids);
for id in ecx.reachable { for &id in ecx.reachable {
rbml_w.wr_tagged_u32(tag_reachable_id, *id); 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(); rbml_w.end_tag();
} }
@ -2139,7 +2159,7 @@ fn encode_metadata_inner(wr: &mut Cursor<Vec<u8>>,
encode_index(&mut rbml_w, items_index); encode_index(&mut rbml_w, items_index);
stats.index_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap() - i; 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(); stats.total_bytes = rbml_w.writer.seek(SeekFrom::Current(0)).unwrap();

View file

@ -8,143 +8,95 @@
// option. This file may not be copied, modified, or distributed // option. This file may not be copied, modified, or distributed
// except according to those terms. // except according to those terms.
use middle::def_id::{DefId, DefIndex};
use rbml;
use rbml::writer::Encoder;
use std::io::{Cursor, Write}; use std::io::{Cursor, Write};
use std::slice; use std::slice;
use std::u32; use std::u32;
use syntax::ast::NodeId;
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)] /// As part of the metadata, we generate an index that stores, for
pub struct IndexEntry { /// each DefIndex, the position of the corresponding RBML document (if
pub node: NodeId, /// any). This is just a big `[u32]` slice, where an entry of
pub pos: u64 /// `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
#[derive(Debug)] /// document, but for looking things up in the metadata, we just
pub struct IndexArrayEntry { /// discard the RBML positioning and jump directly to the data.
bits: u32,
first_pos: u32
}
impl IndexArrayEntry {
fn encode_to<W: Write>(&self, b: &mut W) {
write_be_u32(b, self.bits);
write_be_u32(b, self.first_pos);
}
fn decode_from(b: &[u32]) -> Self {
IndexArrayEntry {
bits: b[0].to_be(),
first_pos: b[1].to_be()
}
}
}
/// 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 { pub struct Index {
position_start: usize, data_start: usize,
index_start: usize, data_end: usize,
index_end: usize,
}
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);
}
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;
}
last_entry.encode_to(buf);
info!("write_index: {} items, {} array entries",
entries.len(), pos_in_index_array);
} }
impl Index { impl Index {
fn lookup_index(&self, index: &[u32], i: u32) -> Option<IndexArrayEntry> { /// Given the RBML doc representing the index, save the offests
let ix = (i as usize)*2; /// for later.
if ix >= index.len() { pub fn from_rbml(index: rbml::Doc) -> Index {
Index { data_start: index.start, data_end: index.end }
}
/// 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 None
} else { } else {
Some(IndexArrayEntry::decode_from(&index[ix..ix+2])) debug!("lookup_item: position={:?}", position);
Some(position)
}
}
}
/// 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>,
}
impl IndexData {
pub fn new(max_index: usize) -> IndexData {
IndexData {
positions: vec![u32::MAX; max_index]
} }
} }
fn item_from_pos(&self, positions: &[u32], pos: u32) -> u32 { pub fn record(&mut self, def_id: DefId, encoder: &mut Encoder) {
positions[pos as usize].to_be() assert!(def_id.is_local());
self.record_index(def_id.index, encoder)
} }
#[inline(never)] pub fn record_index(&mut self, item: DefIndex, encoder: &mut Encoder) {
pub fn lookup_item(&self, buf: &[u8], node: NodeId) -> Option<u32> { let item = item.as_usize();
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 position = encoder.mark_stable_position();
let (x, s) = (node / 32 as u32, node % 32 as u32);
let result = match self.lookup_index(index, x) { assert!(position < (u32::MAX as u64));
Some(IndexArrayEntry { bits, first_pos }) => { let position = position as u32;
let bit = 1<<s;
if bits & bit == 0 { assert!(self.positions[item] == u32::MAX,
None "recorded position for item {:?} twice, first at {:?} and now at {:?}",
} else { item, self.positions[item], position);
let prev_nodes_for_entry = (bits&(bit-1)).count_ones();
Some(self.item_from_pos( self.positions[item] = position;
positions,
first_pos+prev_nodes_for_entry))
}
}
None => None // trailing zero
};
debug!("lookup_item({:?}) = {:?}", node, result);
result
} }
pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self { pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) {
let buf = bytes_to_words(&buf[start..end]); for &position in &self.positions {
let position_count = buf[0].to_be() as usize; write_be_u32(buf, position);
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
} }
} }
} }
@ -162,47 +114,3 @@ fn bytes_to_words(b: &[u8]) -> &[u32] {
assert!(b.len() % 4 == 0); assert!(b.len() % 4 == 0);
unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len()/4) } 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));
}
}

View file

@ -16,11 +16,9 @@
#![allow(non_camel_case_types)] #![allow(non_camel_case_types)]
pub use self::DefIdSource::*;
use rustc_front::hir; use rustc_front::hir;
use middle::def_id::DefId; use middle::def_id::{DefId, DefIndex};
use middle::region; use middle::region;
use middle::subst; use middle::subst;
use middle::subst::VecPerParamSpace; use middle::subst::VecPerParamSpace;
@ -36,32 +34,7 @@ use syntax::parse::token;
// parse_from_str. Extra parameters are for converting to/from def_ids in the // 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. // data buffer. Whatever format you choose should not contain pipe characters.
// Def id conversion: when we encounter def-ids, they have to be translated. pub type DefIdConvert<'a> = &'a mut FnMut(DefId) -> DefId;
// 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 struct TyDecoder<'a, 'tcx: 'a> { pub struct TyDecoder<'a, 'tcx: 'a> {
data: &'a [u8], data: &'a [u8],
@ -183,7 +156,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
ty::BrAnon(id) ty::BrAnon(id)
} }
'[' => { '[' => {
let def = self.parse_def(RegionParameter); let def = self.parse_def();
let name = token::intern(&self.parse_str(']')); let name = token::intern(&self.parse_str(']'));
ty::BrNamed(def, name) ty::BrNamed(def, name)
} }
@ -209,7 +182,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
} }
'B' => { 'B' => {
assert_eq!(self.next(), '['); assert_eq!(self.next(), '[');
let def_id = self.parse_def(NominalType); let def_id = self.parse_def();
let space = self.parse_param_space(); let space = self.parse_param_space();
assert_eq!(self.next(), '|'); assert_eq!(self.next(), '|');
let index = self.parse_u32(); let index = self.parse_u32();
@ -309,7 +282,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
} }
pub fn parse_trait_ref(&mut self) -> ty::TraitRef<'tcx> { 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()); let substs = self.tcx.mk_substs(self.parse_substs());
ty::TraitRef {def_id: def, substs: substs} ty::TraitRef {def_id: def, substs: substs}
} }
@ -338,7 +311,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
'c' => return tcx.types.char, 'c' => return tcx.types.char,
't' => { 't' => {
assert_eq!(self.next(), '['); assert_eq!(self.next(), '[');
let did = self.parse_def(NominalType); let did = self.parse_def();
let substs = self.parse_substs(); let substs = self.parse_substs();
assert_eq!(self.next(), ']'); assert_eq!(self.next(), ']');
let def = self.tcx.lookup_adt_def(did); let def = self.tcx.lookup_adt_def(did);
@ -385,7 +358,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
return tcx.mk_tup(params); return tcx.mk_tup(params);
} }
'F' => { '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())); return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty()));
} }
'G' => { 'G' => {
@ -427,13 +400,13 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
return tt; return tt;
} }
'\"' => { '\"' => {
let _ = self.parse_def(TypeWithId); let _ = self.parse_def();
let inner = self.parse_ty(); let inner = self.parse_ty();
inner inner
} }
'a' => { 'a' => {
assert_eq!(self.next(), '['); assert_eq!(self.next(), '[');
let did = self.parse_def(NominalType); let did = self.parse_def();
let substs = self.parse_substs(); let substs = self.parse_substs();
assert_eq!(self.next(), ']'); assert_eq!(self.next(), ']');
let def = self.tcx.lookup_adt_def(did); let def = self.tcx.lookup_adt_def(did);
@ -441,7 +414,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
} }
'k' => { 'k' => {
assert_eq!(self.next(), '['); assert_eq!(self.next(), '[');
let did = self.parse_def(ClosureSource); let did = self.parse_def();
let substs = self.parse_substs(); let substs = self.parse_substs();
let mut tys = vec![]; let mut tys = vec![];
while self.peek() != '.' { while self.peek() != '.' {
@ -476,9 +449,9 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
ty::TypeAndMut { ty: self.parse_ty(), mutbl: m } 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 == '|')); 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 { fn parse_uint(&mut self) -> usize {
@ -581,7 +554,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(), 'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
'w' => ty::Predicate::WellFormed(self.parse_ty()), 'w' => ty::Predicate::WellFormed(self.parse_ty()),
'O' => { 'O' => {
let def_id = self.parse_def(NominalType); let def_id = self.parse_def();
assert_eq!(self.next(), '|'); assert_eq!(self.next(), '|');
ty::Predicate::ObjectSafe(def_id) ty::Predicate::ObjectSafe(def_id)
} }
@ -601,12 +574,12 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> { pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
let name = self.parse_name(':'); let name = self.parse_name(':');
let def_id = self.parse_def(NominalType); let def_id = self.parse_def();
let space = self.parse_param_space(); let space = self.parse_param_space();
assert_eq!(self.next(), '|'); assert_eq!(self.next(), '|');
let index = self.parse_u32(); let index = self.parse_u32();
assert_eq!(self.next(), '|'); 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 default = self.parse_opt(|this| this.parse_ty());
let object_lifetime_default = self.parse_object_lifetime_default(); let object_lifetime_default = self.parse_object_lifetime_default();
@ -623,7 +596,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef { pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
let name = self.parse_name(':'); let name = self.parse_name(':');
let def_id = self.parse_def(NominalType); let def_id = self.parse_def();
let space = self.parse_param_space(); let space = self.parse_param_space();
assert_eq!(self.next(), '|'); assert_eq!(self.next(), '|');
let index = self.parse_u32(); let index = self.parse_u32();
@ -731,11 +704,12 @@ fn parse_defid(buf: &[u8]) -> DefId {
let def_num = match str::from_utf8(def_part).ok().and_then(|s| { let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
s.parse::<usize>().ok() s.parse::<usize>().ok()
}) { }) {
Some(dn) => dn as ast::NodeId, Some(dn) => dn,
None => panic!("internal error: parse_defid: id expected, found {:?}", None => panic!("internal error: parse_defid: id expected, found {:?}",
def_part) 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 { fn parse_unsafety(c: char) -> hir::Unsafety {

View file

@ -19,14 +19,11 @@ use rustc_front::fold::Folder;
use metadata::common as c; use metadata::common as c;
use metadata::cstore as cstore; use metadata::cstore as cstore;
use metadata::cstore::LOCAL_CRATE;
use session::Session; use session::Session;
use metadata::decoder; use metadata::decoder;
use metadata::encoder as e; use metadata::encoder as e;
use metadata::inline::{InlinedItem, InlinedItemRef}; use metadata::inline::{InlinedItem, InlinedItemRef};
use metadata::tydecode; use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId};
use metadata::tydecode::{RegionParameter, ClosureSource};
use metadata::tyencode; use metadata::tyencode;
use middle::ty::adjustment; use middle::ty::adjustment;
use middle::ty::cast; use middle::ty::cast;
@ -73,10 +70,6 @@ trait tr {
fn tr(&self, dcx: &DecodeContext) -> Self; fn tr(&self, dcx: &DecodeContext) -> Self;
} }
trait tr_intern {
fn tr_intern(&self, dcx: &DecodeContext) -> DefId;
}
// ______________________________________________________________________ // ______________________________________________________________________
// Top-level methods. // Top-level methods.
@ -130,10 +123,12 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata, pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
tcx: &ty::ctxt<'tcx>, tcx: &ty::ctxt<'tcx>,
path: Vec<ast_map::PathElem>, path: Vec<ast_map::PathElem>,
def_path: ast_map::DefPath,
par_doc: rbml::Doc) 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) { match par_doc.opt_child(c::tag_ast) {
None => Err(path), None => Err((path, def_path)),
Some(ast_doc) => { Some(ast_doc) => {
let mut path_as_str = None; let mut path_as_str = None;
debug!("> Decoding inlined fn: {:?}::?", debug!("> Decoding inlined fn: {:?}::?",
@ -154,7 +149,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
last_filemap_index: Cell::new(0) last_filemap_index: Cell::new(0)
}; };
let raw_ii = decode_ast(ast_doc); 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 { let name = match *ii {
InlinedItem::Item(ref i) => i.name, InlinedItem::Item(ref i) => i.name,
@ -214,24 +209,10 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
/// be inlined. Note that even when the inlined function is referencing itself recursively, we /// 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, /// 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. /// 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 { pub fn tr_def_id(&self, did: DefId) -> DefId {
decoder::translate_def_id(self.cdata, did) 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` /// Translates a `Span` from an extern crate to the corresponding `Span`
/// within the local crate's codemap. `creader::import_codemap()` will /// within the local crate's codemap. `creader::import_codemap()` will
/// already have allocated any additionally needed FileMaps in the local /// already have allocated any additionally needed FileMaps in the local
@ -290,12 +271,6 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
} }
} }
impl tr_intern for DefId {
fn tr_intern(&self, dcx: &DecodeContext) -> DefId {
dcx.tr_intern_def_id(*self)
}
}
impl tr for DefId { impl tr for DefId {
fn tr(&self, dcx: &DecodeContext) -> DefId { fn tr(&self, dcx: &DecodeContext) -> DefId {
dcx.tr_def_id(*self) dcx.tr_def_id(*self)
@ -575,10 +550,6 @@ impl<'a, 'tcx> read_method_callee_helper<'tcx> for reader::Decoder<'a> {
} }
} }
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) { pub fn encode_cast_kind(ebml_w: &mut Encoder, kind: cast::CastKind) {
kind.encode(ebml_w).unwrap(); kind.encode(ebml_w).unwrap();
} }
@ -632,8 +603,6 @@ impl<'a, 'tcx> get_ty_str_ctxt<'tcx> for e::EncodeContext<'a, 'tcx> {
} }
trait rbml_writer_helpers<'tcx> { trait rbml_writer_helpers<'tcx> {
fn emit_closure_type<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
closure_type: &ty::ClosureTy<'tcx>);
fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region); fn emit_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_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>]); fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
@ -662,14 +631,6 @@ trait rbml_writer_helpers<'tcx> {
} }
impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> { 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) { fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region) {
self.emit_opaque(|this| Ok(e::write_region(ecx, this, r))); self.emit_opaque(|this| Ok(e::write_region(ecx, this, r)));
} }
@ -1005,24 +966,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
}) })
} }
if let Some(def_id) = opt_def_id {
if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&def_id) {
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
rbml_w.id(id);
rbml_w.emit_closure_type(ecx, closure_type);
})
}
}
if let Some(def_id) = opt_def_id {
if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&def_id) {
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
rbml_w.id(id);
encode_closure_kind(rbml_w, *closure_kind)
})
}
}
if let Some(cast_kind) = tcx.cast_kinds.borrow().get(&id) { if let Some(cast_kind) = tcx.cast_kinds.borrow().get(&id) {
rbml_w.tag(c::tag_table_cast_kinds, |rbml_w| { rbml_w.tag(c::tag_table_cast_kinds, |rbml_w| {
rbml_w.id(id); rbml_w.id(id);
@ -1080,17 +1023,12 @@ trait rbml_decoder_decoder_helpers<'tcx> {
-> adjustment::AutoAdjustment<'tcx>; -> adjustment::AutoAdjustment<'tcx>;
fn read_cast_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) fn read_cast_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> cast::CastKind; -> 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>) fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> adjustment::AutoDerefRef<'tcx>; -> adjustment::AutoDerefRef<'tcx>;
fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>) fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> adjustment::AutoRef<'tcx>; -> adjustment::AutoRef<'tcx>;
fn convert_def_id(&mut self, fn convert_def_id(&mut self,
dcx: &DecodeContext, dcx: &DecodeContext,
source: DefIdSource,
did: DefId) did: DefId)
-> DefId; -> DefId;
@ -1114,7 +1052,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
self.read_opaque(|_, doc| { self.read_opaque(|_, doc| {
Ok( Ok(
tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc, 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()) .parse_ty())
}).unwrap() }).unwrap()
} }
@ -1136,7 +1074,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
self.read_opaque(|_, doc| { self.read_opaque(|_, doc| {
Ok( Ok(
tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc, 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()) .parse_substs())
}).unwrap() }).unwrap()
} }
@ -1149,7 +1087,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
Ok(op( Ok(op(
&mut tydecode::TyDecoder::with_doc( &mut tydecode::TyDecoder::with_doc(
dcx.tcx, dcx.cdata.cnum, 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(); }).unwrap();
fn type_string(doc: rbml::Doc) -> String { fn type_string(doc: rbml::Doc) -> String {
@ -1238,7 +1176,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
-> subst::Substs<'tcx> { -> subst::Substs<'tcx> {
self.read_opaque(|this, doc| { self.read_opaque(|this, doc| {
Ok(tydecode::TyDecoder::with_doc(dcx.tcx, dcx.cdata.cnum, 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()) .parse_substs())
}).unwrap() }).unwrap()
} }
@ -1345,18 +1283,6 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
Decodable::decode(self).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 /// Converts a def-id that appears in a type. The correct
/// translation will depend on what kind of def-id this is. /// translation will depend on what kind of def-id this is.
/// This is a subtle point: type definitions are not /// This is a subtle point: type definitions are not
@ -1391,14 +1317,10 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
/// def-ids so that all these distinctions were unnecessary. /// def-ids so that all these distinctions were unnecessary.
fn convert_def_id(&mut self, fn convert_def_id(&mut self,
dcx: &DecodeContext, dcx: &DecodeContext,
source: tydecode::DefIdSource,
did: DefId) did: DefId)
-> DefId { -> DefId {
let r = match source { let r = dcx.tr_def_id(did);
NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did), debug!("convert_def_id(did={:?})={:?}", did, r);
ClosureSource => dcx.tr_intern_def_id(did)
};
debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
return r; return r;
} }
} }
@ -1485,20 +1407,6 @@ fn decode_side_tables(dcx: &DecodeContext,
val_dsr.read_auto_adjustment(dcx); val_dsr.read_auto_adjustment(dcx);
dcx.tcx.tables.borrow_mut().adjustments.insert(id, adj); 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 => { c::tag_table_cast_kinds => {
let cast_kind = let cast_kind =
val_dsr.read_cast_kind(dcx); val_dsr.read_cast_kind(dcx);

View file

@ -92,7 +92,7 @@ fn lookup_variant_by_id<'a>(tcx: &'a ty::ctxt,
let expr_id = match let expr_id = match
csearch::maybe_get_item_ast( csearch::maybe_get_item_ast(
tcx, enum_def, 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 { csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
hir::ItemEnum(hir::EnumDef { .. }, _) => { hir::ItemEnum(hir::EnumDef { .. }, _) => {
@ -168,7 +168,7 @@ pub fn lookup_const_by_id<'a, 'tcx: 'a>(tcx: &'a ty::ctxt<'tcx>,
} }
let mut used_ref_id = false; let mut used_ref_id = false;
let expr_id = match csearch::maybe_get_item_ast(tcx, def_id, 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 { csearch::FoundAst::Found(&InlinedItem::Item(ref item)) => match item.node {
hir::ItemConst(_, ref const_expr) => Some(const_expr.id), hir::ItemConst(_, ref const_expr) => Some(const_expr.id),
_ => None _ => None
@ -224,7 +224,7 @@ fn inline_const_fn_from_external_crate(tcx: &ty::ctxt, def_id: DefId)
} }
let fn_id = match csearch::maybe_get_item_ast(tcx, def_id, 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::Item(ref item)) => Some(item.id),
csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id), csearch::FoundAst::Found(&InlinedItem::ImplItem(_, ref item)) => Some(item.id),
_ => None _ => None

View file

@ -10,20 +10,53 @@
use metadata::cstore::LOCAL_CRATE; use metadata::cstore::LOCAL_CRATE;
use middle::ty; use middle::ty;
use syntax::ast::{CrateNum, NodeId}; use syntax::ast::CrateNum;
use std::fmt; 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, #[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
RustcDecodable, Hash, Copy)] RustcDecodable, Hash, Copy)]
pub struct DefId { pub struct DefId {
pub krate: CrateNum, pub krate: CrateNum,
pub xxx_node: NodeId, pub index: DefIndex,
} }
impl fmt::Debug for DefId { impl fmt::Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "DefId {{ krate: {}, node: {}", try!(write!(f, "DefId {{ krate: {:?}, node: {:?}",
self.krate, self.xxx_node)); self.krate, self.index));
// Unfortunately, there seems to be no way to attempt to print // 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 // a path for a def-id, so I'll just make a best effort for now
@ -41,8 +74,8 @@ impl fmt::Debug for DefId {
impl DefId { impl DefId {
pub fn xxx_local(id: NodeId) -> DefId { pub fn local(index: DefIndex) -> DefId {
DefId { krate: LOCAL_CRATE, xxx_node: id } DefId { krate: LOCAL_CRATE, index: index }
} }
pub fn is_local(&self) -> bool { pub fn is_local(&self) -> bool {

View file

@ -276,7 +276,7 @@ enum PassArgs {
} }
impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> { 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>) typer: &'t infer::InferCtxt<'a, 'tcx>)
-> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a -> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a
{ {

View file

@ -1455,7 +1455,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
def_id: DefId) def_id: DefId)
-> Option<ty::ClosureKind> -> 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, pub fn closure_type(&self,
@ -1463,12 +1471,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
substs: &ty::ClosureSubsts<'tcx>) substs: &ty::ClosureSubsts<'tcx>)
-> ty::ClosureTy<'tcx> -> ty::ClosureTy<'tcx>
{ {
let closure_ty = self.tables let closure_ty =
.borrow() ty::Tables::closure_type(self.tables,
.closure_tys self.tcx,
.get(&def_id) def_id,
.unwrap() substs);
.subst(self.tcx, &substs.func_substs);
if self.normalize { if self.normalize {
normalize_associated_type(&self.tcx, &closure_ty) normalize_associated_type(&self.tcx, &closure_ty)

View file

@ -208,8 +208,8 @@ impl<'a, 'tcx> LanguageItemCollector<'a, 'tcx> {
pub fn collect_external_language_items(&mut self) { pub fn collect_external_language_items(&mut self) {
let crate_store = &self.session.cstore; let crate_store = &self.session.cstore;
crate_store.iter_crate_data(|crate_number, _crate_metadata| { crate_store.iter_crate_data(|crate_number, _crate_metadata| {
each_lang_item(crate_store, crate_number, |node_id, item_index| { each_lang_item(crate_store, crate_number, |index, item_index| {
let def_id = DefId { krate: crate_number, xxx_node: node_id }; let def_id = DefId { krate: crate_number, index: index };
self.collect_item(item_index, def_id, DUMMY_SP); self.collect_item(item_index, def_id, DUMMY_SP);
true true
}); });

View file

@ -15,7 +15,7 @@ use session::Session;
use lint; use lint;
use metadata::cstore::LOCAL_CRATE; use metadata::cstore::LOCAL_CRATE;
use middle::def; use middle::def;
use middle::def_id::DefId; use middle::def_id::{CRATE_DEF_INDEX, DefId};
use middle::ty; use middle::ty;
use middle::privacy::PublicItems; use middle::privacy::PublicItems;
use metadata::csearch; use metadata::csearch;
@ -383,7 +383,7 @@ pub fn check_item(tcx: &ty::ctxt, item: &hir::Item, warn_about_defns: bool,
Some(cnum) => cnum, Some(cnum) => cnum,
None => return, 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); maybe_do_stability_check(tcx, id, item.span, cb);
} }

View file

@ -37,7 +37,6 @@ use super::{VtableImplData, VtableObjectData, VtableBuiltinData,
use super::object_safety; use super::object_safety;
use super::util; use super::util;
use metadata::cstore::LOCAL_CRATE;
use middle::def_id::DefId; use middle::def_id::DefId;
use middle::infer; use middle::infer;
use middle::infer::{InferCtxt, TypeFreshener}; use middle::infer::{InferCtxt, TypeFreshener};
@ -1720,7 +1719,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// (T1, ..., Tn) -- meets any bound that all of T1...Tn meet // (T1, ..., Tn) -- meets any bound that all of T1...Tn meet
ty::TyTuple(ref tys) => ok_if(tys.clone()), 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 // FIXME -- This case is tricky. In the case of by-ref
// closures particularly, we need the results of // closures particularly, we need the results of
// inference to decide how to reflect the type of each // inference to decide how to reflect the type of each
@ -1730,7 +1729,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// captures are by value. Really what we ought to do // captures are by value. Really what we ought to do
// is reserve judgement and then intertwine this // is reserve judgement and then intertwine this
// analysis with closure inference. // analysis with closure inference.
assert_eq!(def_id.krate, LOCAL_CRATE);
// Unboxed closures shouldn't be // Unboxed closures shouldn't be
// implicitly copyable // implicitly copyable
@ -1864,7 +1862,7 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
tys.clone() tys.clone()
} }
ty::TyClosure(def_id, ref substs) => { ty::TyClosure(_, ref substs) => {
// FIXME(#27086). We are invariant w/r/t our // FIXME(#27086). We are invariant w/r/t our
// substs.func_substs, but we don't see them as // substs.func_substs, but we don't see them as
// constituent types; this seems RIGHT but also like // constituent types; this seems RIGHT but also like
@ -1873,7 +1871,6 @@ impl<'cx, 'tcx> SelectionContext<'cx, 'tcx> {
// OIBIT interact? That is, there is no way to say // OIBIT interact? That is, there is no way to say
// "make me invariant with respect to this TYPE, but // "make me invariant with respect to this TYPE, but
// do not act as though I can reach it" // do not act as though I can reach it"
assert_eq!(def_id.krate, LOCAL_CRATE);
substs.upvar_tys.clone() substs.upvar_tys.clone()
} }

View file

@ -16,6 +16,7 @@
use front::map as ast_map; use front::map as ast_map;
use session::Session; use session::Session;
use lint; use lint;
use metadata::csearch;
use middle; use middle;
use middle::def::DefMap; use middle::def::DefMap;
use middle::def_id::DefId; use middle::def_id::DefId;
@ -134,6 +135,40 @@ impl<'tcx> Tables<'tcx> {
closure_kinds: DefIdMap(), 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> { impl<'tcx> CommonTypes<'tcx> {
@ -336,19 +371,8 @@ pub struct ctxt<'tcx> {
/// constitute it. /// constitute it.
pub fragment_infos: RefCell<DefIdMap<Vec<ty::FragmentInfo>>>, pub fragment_infos: RefCell<DefIdMap<Vec<ty::FragmentInfo>>>,
} }
impl<'tcx> ctxt<'tcx> { 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)
}
pub fn type_parameter_def(&self, pub fn type_parameter_def(&self,
node_id: NodeId) node_id: NodeId)
-> ty::TypeParameterDef<'tcx> -> ty::TypeParameterDef<'tcx>

View file

@ -2263,6 +2263,14 @@ impl<'tcx> ctxt<'tcx> {
self.with_path(id, |path| ast_map::path_to_string(path)) 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 pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
F: FnOnce(ast_map::PathElems) -> T, F: FnOnce(ast_map::PathElems) -> T,
{ {
@ -2480,6 +2488,18 @@ impl<'tcx> ctxt<'tcx> {
def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID); 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. /// Given the def_id of an impl, return the def_id of the trait it implements.
/// If it implements no trait, return `None`. /// If it implements no trait, return `None`.
pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> { pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
@ -2800,3 +2820,4 @@ pub trait HasTypeFlags {
!self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES) !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES)
} }
} }

View file

@ -461,7 +461,7 @@ impl<'tcx> ty::ctxt<'tcx> {
tcx.sess.cstore.get_crate_hash(did.krate) tcx.sess.cstore.get_crate_hash(did.krate)
}; };
h.as_str().hash(state); h.as_str().hash(state);
did.xxx_node.hash(state); did.index.hash(state);
}; };
let mt = |state: &mut SipHasher, mt: TypeAndMut| { let mt = |state: &mut SipHasher, mt: TypeAndMut| {
mt.mutbl.hash(state); mt.mutbl.hash(state);

View file

@ -27,7 +27,7 @@ use std::fmt;
use syntax::abi; use syntax::abi;
use syntax::ast; use syntax::ast;
use syntax::parse::token; use syntax::parse::token;
use syntax::ast::{CRATE_NODE_ID}; use syntax::ast::CRATE_NODE_ID;
use rustc_front::hir; use rustc_front::hir;
pub fn verbose() -> bool { pub fn verbose() -> bool {

View file

@ -901,20 +901,22 @@ impl LateLintPass for UnconditionalRecursion {
fn expr_refers_to_this_method(tcx: &ty::ctxt, fn expr_refers_to_this_method(tcx: &ty::ctxt,
method: &ty::Method, method: &ty::Method,
id: ast::NodeId) -> bool { id: ast::NodeId) -> bool {
let tables = tcx.tables.borrow();
// Check for method calls and overloaded operators. // 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) { if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) {
return true; return true;
} }
} }
// Check for overloaded autoderef method calls. // 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 { for i in 0..adj.autoderefs {
let method_call = ty::MethodCall::autoderef(id, i as u32); 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) { if method_call_refers_to_method(tcx, method, m.def_id, m.substs, id) {
return true; return true;
} }
@ -927,9 +929,13 @@ impl LateLintPass for UnconditionalRecursion {
hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => { hir_map::NodeExpr(&hir::Expr { node: hir::ExprCall(ref callee, _), .. }) => {
match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) { match tcx.def_map.borrow().get(&callee.id).map(|d| d.full_def()) {
Some(def::DefMethod(def_id)) => { Some(def::DefMethod(def_id)) => {
let no_substs = &ty::ItemSubsts::empty(); let item_substs =
let ts = tables.item_substs.get(&callee.id).unwrap_or(no_substs); tcx.tables.borrow().item_substs
method_call_refers_to_method(tcx, method, def_id, &ts.substs, id) .get(&callee.id)
.cloned()
.unwrap_or_else(|| ty::ItemSubsts::empty());
method_call_refers_to_method(
tcx, method, def_id, &item_substs.substs, id)
} }
_ => false _ => false
} }

View file

@ -34,7 +34,7 @@ use self::NamespaceError::*;
use rustc::metadata::csearch; use rustc::metadata::csearch;
use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl}; use rustc::metadata::decoder::{DefLike, DlDef, DlField, DlImpl};
use rustc::middle::def::*; 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::ast::{Name, NodeId};
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
@ -387,7 +387,7 @@ impl<'a, 'b:'a, 'tcx:'b> GraphBuilder<'a, 'b, 'tcx> {
ItemExternCrate(_) => { ItemExternCrate(_) => {
// n.b. we don't need to look at the path option here, because cstore already did // 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) { 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); self.external_exports.insert(def_id);
let parent_link = ModuleParentLink(Rc::downgrade(parent), name); let parent_link = ModuleParentLink(Rc::downgrade(parent), name);
let external_module = Rc::new(Module::new(parent_link, let external_module = Rc::new(Module::new(parent_link,

View file

@ -25,7 +25,7 @@ use metadata::loader::METADATA_FILENAME;
use metadata::{encoder, cstore, filesearch, csearch, creader}; use metadata::{encoder, cstore, filesearch, csearch, creader};
use middle::dependency_format::Linkage; use middle::dependency_format::Linkage;
use middle::ty::{self, Ty}; use middle::ty::{self, Ty};
use rustc::front::map::{PathElem, PathElems, PathName}; use rustc::front::map::DefPath;
use trans::{CrateContext, CrateTranslation, gensym_name}; use trans::{CrateContext, CrateTranslation, gensym_name};
use util::common::time; use util::common::time;
use util::sha2::{Digest, Sha256}; use util::sha2::{Digest, Sha256};
@ -36,6 +36,7 @@ use std::env;
use std::ffi::OsString; use std::ffi::OsString;
use std::fs::{self, PathExt}; use std::fs::{self, PathExt};
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
use std::iter::once;
use std::mem; use std::mem;
use std::path::{Path, PathBuf}; use std::path::{Path, PathBuf};
use std::process::Command; use std::process::Command;
@ -44,7 +45,7 @@ use flate;
use serialize::hex::ToHex; use serialize::hex::ToHex;
use syntax::ast; use syntax::ast;
use syntax::codemap::Span; use syntax::codemap::Span;
use syntax::parse::token; use syntax::parse::token::{self, InternedString};
use syntax::attr::AttrMetaMethods; use syntax::attr::AttrMetaMethods;
use rustc_front::hir; use rustc_front::hir;
@ -284,8 +285,7 @@ pub fn sanitize(s: &str) -> String {
return result; return result;
} }
pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI, pub fn mangle<PI: Iterator<Item=InternedString>>(path: PI, hash: Option<&str>) -> String {
hash: Option<&str>) -> String {
// Follow C++ namespace-mangling style, see // Follow C++ namespace-mangling style, see
// http://en.wikipedia.org/wiki/Name_mangling for more info. // http://en.wikipedia.org/wiki/Name_mangling for more info.
// //
@ -308,8 +308,8 @@ pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI,
} }
// First, connect each component with <len, name> pairs. // First, connect each component with <len, name> pairs.
for e in path { for data in path {
push(&mut n, &e.name().as_str()) push(&mut n, &data);
} }
match hash { match hash {
@ -321,11 +321,13 @@ pub fn mangle<PI: Iterator<Item=PathElem>>(path: PI,
n 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)) 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 { t: Ty<'tcx>, id: ast::NodeId) -> String {
let mut hash = get_symbol_hash(ccx, t); let mut hash = get_symbol_hash(ccx, t);
@ -353,14 +355,17 @@ pub fn mangle_exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, path: PathEl
pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, pub fn mangle_internal_name_by_type_and_seq<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
t: Ty<'tcx>, t: Ty<'tcx>,
name: &str) -> String { name: &str) -> String {
let path = [PathName(token::intern(&t.to_string())), let path = [token::intern(&t.to_string()).as_str(), gensym_name(name).as_str()];
gensym_name(name)];
let hash = get_symbol_hash(ccx, t); let hash = get_symbol_hash(ccx, t);
mangle(path.iter().cloned(), Some(&hash[..])) mangle(path.iter().cloned(), Some(&hash[..]))
} }
pub fn mangle_internal_name_by_path_and_seq(path: PathElems, flav: &str) -> String { pub fn mangle_internal_name_by_path_and_seq(path: DefPath, flav: &str) -> String {
mangle(path.chain(Some(gensym_name(flav))), None) 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) { pub fn get_linker(sess: &Session) -> (String, Command) {

View file

@ -13,7 +13,8 @@ pub use self::Row::*;
use super::escape; use super::escape;
use super::span_utils::SpanUtils; 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 std::io::Write;
@ -21,7 +22,7 @@ use syntax::ast;
use syntax::ast::NodeId; use syntax::ast::NodeId;
use syntax::codemap::*; 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 { pub struct Recorder {
// output file // output file
@ -381,7 +382,7 @@ impl<'a> FmtStrs<'a> {
decl_id: Option<DefId>, decl_id: Option<DefId>,
scope_id: NodeId) { scope_id: NodeId) {
let values = match decl_id { 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), None => svec!(id, name, "", "", scope_id),
}; };
self.check_and_record(Function, self.check_and_record(Function,
@ -436,15 +437,15 @@ impl<'a> FmtStrs<'a> {
ref_id: Option<DefId>, ref_id: Option<DefId>,
trait_id: Option<DefId>, trait_id: Option<DefId>,
scope_id: NodeId) { scope_id: NodeId) {
let ref_id = ref_id.unwrap_or(ZERO_DEF_ID); let ref_id = ref_id.unwrap_or(CRATE_ROOT_DEF_ID);
let trait_id = trait_id.unwrap_or(ZERO_DEF_ID); let trait_id = trait_id.unwrap_or(CRATE_ROOT_DEF_ID);
self.check_and_record(Impl, self.check_and_record(Impl,
span, span,
sub_span, sub_span,
svec!(id, svec!(id,
ref_id.xxx_node, ref_id.index.as_usize(),
ref_id.krate, ref_id.krate,
trait_id.xxx_node, trait_id.index.as_usize(),
trait_id.krate, trait_id.krate,
scope_id)); scope_id));
} }
@ -469,14 +470,11 @@ impl<'a> FmtStrs<'a> {
mod_id: Option<DefId>, mod_id: Option<DefId>,
name: &str, name: &str,
parent: NodeId) { parent: NodeId) {
let (mod_node, mod_crate) = match mod_id { let mod_id = mod_id.unwrap_or(CRATE_ROOT_DEF_ID);
Some(mod_id) => (mod_id.xxx_node, mod_id.krate),
None => (0, 0),
};
self.check_and_record(UseAlias, self.check_and_record(UseAlias,
span, span,
sub_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, pub fn use_glob_str(&mut self,
@ -513,7 +511,7 @@ impl<'a> FmtStrs<'a> {
self.check_and_record(Inheritance, self.check_and_record(Inheritance,
span, span,
sub_span, sub_span,
svec!(base_id.xxx_node, svec!(base_id.index.as_usize(),
base_id.krate, base_id.krate,
deriv_id, deriv_id,
0)); 0));
@ -527,7 +525,7 @@ impl<'a> FmtStrs<'a> {
self.check_and_record(FnCall, self.check_and_record(FnCall,
span, span,
sub_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, pub fn meth_call_str(&mut self,
@ -536,18 +534,15 @@ impl<'a> FmtStrs<'a> {
defid: Option<DefId>, defid: Option<DefId>,
declid: Option<DefId>, declid: Option<DefId>,
scope_id: NodeId) { scope_id: NodeId) {
let (dfn, dfk) = match defid { let defid = defid.unwrap_or(CRATE_ROOT_DEF_ID);
Some(defid) => (defid.xxx_node, defid.krate),
None => (0, 0),
};
let (dcn, dck) = match declid { 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()), None => ("".to_string(), "".to_string()),
}; };
self.check_and_record(MethodCall, self.check_and_record(MethodCall,
span, span,
sub_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) { pub fn sub_mod_ref_str(&mut self, span: Span, sub_span: Span, qualname: &str, parent: NodeId) {
@ -600,6 +595,6 @@ impl<'a> FmtStrs<'a> {
self.check_and_record(kind, self.check_and_record(kind,
span, span,
sub_span, sub_span,
svec!(id.xxx_node, id.krate, "", scope_id)); svec!(id.index.as_usize(), id.krate, "", scope_id));
} }
} }

View file

@ -1576,7 +1576,7 @@ pub fn trans_closure<'a, 'b, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
param_substs); param_substs);
let has_env = match closure_env { let has_env = match closure_env {
closure::ClosureEnv::Closure(_) => true, closure::ClosureEnv::Closure(..) => true,
closure::ClosureEnv::NotClosure => false, closure::ClosureEnv::NotClosure => false,
}; };
@ -2309,10 +2309,11 @@ fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, id: ast::NodeId,
match attr::find_export_name_attr(ccx.sess().diagnostic(), attrs) { match attr::find_export_name_attr(ccx.sess().diagnostic(), attrs) {
// Use provided name // Use provided name
Some(name) => name.to_string(), 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") { if attr::contains_name(attrs, "no_mangle") {
// Don't mangle // Don't mangle
path.last().unwrap().to_string() path.last().unwrap().data.to_string()
} else { } else {
match weak_lang_items::link_name(attrs) { match weak_lang_items::link_name(attrs) {
Some(name) => name.to_string(), Some(name) => name.to_string(),
@ -2322,7 +2323,7 @@ fn exported_name<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, id: ast::NodeId,
} }
} }
} }
}) }
} }
} }

View file

@ -36,6 +36,7 @@ use rustc_front::hir;
fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>, fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
closure_def_id: DefId,
arg_scope_id: ScopeId, arg_scope_id: ScopeId,
freevars: &[ty::Freevar]) freevars: &[ty::Freevar])
-> Block<'blk, 'tcx> -> Block<'blk, 'tcx>
@ -43,9 +44,9 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
let _icx = push_ctxt("closure::load_closure_environment"); let _icx = push_ctxt("closure::load_closure_environment");
// Special case for small by-value selfs. // Special case for small by-value selfs.
let closure_id = bcx.tcx().map.local_def_id(bcx.fcx.id); let closure_ty = node_id_type(bcx, bcx.fcx.id);
let self_type = self_type_for_closure(bcx.ccx(), closure_id, 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_id); let kind = kind_for_closure(bcx.ccx(), closure_def_id);
let llenv = if kind == ty::FnOnceClosureKind && let llenv = if kind == ty::FnOnceClosureKind &&
!arg_is_indirect(bcx.ccx(), self_type) { !arg_is_indirect(bcx.ccx(), self_type) {
let datum = rvalue_scratch_datum(bcx, let datum = rvalue_scratch_datum(bcx,
@ -106,7 +107,7 @@ fn load_closure_environment<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
pub enum ClosureEnv<'a> { pub enum ClosureEnv<'a> {
NotClosure, NotClosure,
Closure(&'a [ty::Freevar]), Closure(DefId, &'a [ty::Freevar]),
} }
impl<'a> ClosureEnv<'a> { impl<'a> ClosureEnv<'a> {
@ -115,11 +116,11 @@ impl<'a> ClosureEnv<'a> {
{ {
match self { match self {
ClosureEnv::NotClosure => bcx, ClosureEnv::NotClosure => bcx,
ClosureEnv::Closure(freevars) => { ClosureEnv::Closure(def_id, freevars) => {
if freevars.is_empty() { if freevars.is_empty() {
bcx bcx
} else { } else {
load_closure_environment(bcx, arg_scope, freevars) load_closure_environment(bcx, def_id, arg_scope, freevars)
} }
} }
} }
@ -132,8 +133,6 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
closure_id: DefId, closure_id: DefId,
substs: &ty::ClosureSubsts<'tcx>) substs: &ty::ClosureSubsts<'tcx>)
-> ValueRef { -> 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 // Normalize type so differences in regions and typedefs don't cause
// duplicate declarations // duplicate declarations
let substs = ccx.tcx().erase_regions(substs); let substs = ccx.tcx().erase_regions(substs);
@ -148,9 +147,8 @@ pub fn get_or_create_closure_declaration<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
return llfn; return llfn;
} }
let symbol = ccx.tcx().map.with_path(closure_node_id, |path| { let path = ccx.tcx().def_path(closure_id);
mangle_internal_name_by_path_and_seq(path, "closure") 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 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); let llfn = declare::define_internal_rust_fn(ccx, &symbol[..], function_type);
@ -177,9 +175,14 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
decl: &hir::FnDecl, decl: &hir::FnDecl,
body: &hir::Block, body: &hir::Block,
id: ast::NodeId, id: ast::NodeId,
closure_def_id: DefId, // (*)
closure_substs: &'tcx ty::ClosureSubsts<'tcx>) closure_substs: &'tcx ty::ClosureSubsts<'tcx>)
-> Option<Block<'a, '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 param_substs = closure_substs.func_substs;
let ccx = match dest { let ccx = match dest {
@ -189,10 +192,10 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
let tcx = ccx.tcx(); let tcx = ccx.tcx();
let _icx = push_ctxt("closure::trans_closure_expr"); 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_def_id, closure_substs);
let llfn = get_or_create_closure_declaration(ccx, closure_id, closure_substs);
// Get the type of this closure. Use the current `param_substs` as // Get the type of this closure. Use the current `param_substs` as
// the closure substitutions. This makes sense because the closure // the closure substitutions. This makes sense because the closure
@ -201,7 +204,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
// of the closure expression. // of the closure expression.
let infcx = infer::normalizing_infer_ctxt(ccx.tcx(), &ccx.tcx().tables); 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> = let freevars: Vec<ty::Freevar> =
tcx.with_freevars(id, |fv| fv.iter().cloned().collect()); tcx.with_freevars(id, |fv| fv.iter().cloned().collect());
@ -217,7 +220,7 @@ pub fn trans_closure_expr<'a, 'tcx>(dest: Dest<'a, 'tcx>,
&[], &[],
sig.output, sig.output,
function_type.abi, 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 // 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 // to have a zero-size closure (in which case dest will be `Ignore`) and

View file

@ -39,7 +39,6 @@ use trans::type_of;
use middle::traits; use middle::traits;
use middle::ty::{self, HasTypeFlags, Ty}; use middle::ty::{self, HasTypeFlags, Ty};
use middle::ty::fold::{TypeFolder, TypeFoldable}; use middle::ty::fold::{TypeFolder, TypeFoldable};
use rustc::front::map::{PathElem, PathName};
use rustc_front::hir; use rustc_front::hir;
use util::nodemap::{FnvHashMap, NodeMap}; use util::nodemap::{FnvHashMap, NodeMap};
@ -167,11 +166,11 @@ pub fn return_type_is_void(ccx: &CrateContext, ty: Ty) -> bool {
/// Generates a unique symbol based off the name given. This is used to create /// Generates a unique symbol based off the name given. This is used to create
/// unique symbols for things like closures. /// 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; let num = token::gensym(name).0;
// use one colon which will get translated to a period by the mangler, and // 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. // we're guaranteed that `num` is globally unique for this crate.
PathName(token::gensym(&format!("{}:{}", name, num))) token::gensym(&format!("{}:{}", name, num))
} }
/* /*
@ -1020,7 +1019,7 @@ pub fn fulfill_obligation<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
trait_ref); trait_ref);
ccx.sess().span_fatal( ccx.sess().span_fatal(
span, span,
"reached the recursion limit during monomorphization"); "reached the recursion limit during monomorphization (selection ambiguity)");
} }
Err(e) => { Err(e) => {
tcx.sess.span_bug( tcx.sess.span_bug(

View file

@ -877,9 +877,9 @@ fn const_expr_unadjusted<'a, 'tcx>(cx: &CrateContext<'a, 'tcx>,
}, },
hir::ExprClosure(_, ref decl, ref body) => { hir::ExprClosure(_, ref decl, ref body) => {
match ety.sty { match ety.sty {
ty::TyClosure(_, ref substs) => { ty::TyClosure(def_id, ref substs) => {
closure::trans_closure_expr(closure::Dest::Ignore(cx), decl, closure::trans_closure_expr(closure::Dest::Ignore(cx), decl,
body, e.id, substs); body, e.id, def_id, substs);
} }
_ => _ =>
cx.sess().span_bug( cx.sess().span_bug(

View file

@ -346,7 +346,7 @@ impl<'tcx> TypeMap<'tcx> {
output.push_str(crate_hash.as_str()); output.push_str(crate_hash.as_str());
output.push_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. // Maybe check that there is no self type here.

View file

@ -1195,14 +1195,23 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest), SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest),
Ignore => closure::Dest::Ignore(bcx.ccx()) 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 => ref t =>
bcx.tcx().sess.span_bug( bcx.tcx().sess.span_bug(
expr.span, expr.span,
&format!("closure expr without closure type: {:?}", t)), &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) => { hir::ExprCall(ref f, ref args) => {
if bcx.tcx().is_method_call(expr.id) { if bcx.tcx().is_method_call(expr.id) {

View file

@ -29,9 +29,9 @@ use trans::type_of::*;
use trans::type_of; use trans::type_of;
use middle::ty::{self, Ty}; use middle::ty::{self, Ty};
use middle::subst::Substs; use middle::subst::Substs;
use rustc::front::map as hir_map;
use std::cmp; use std::cmp;
use std::iter::once;
use libc::c_uint; use libc::c_uint;
use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi}; use syntax::abi::{Cdecl, Aapcs, C, Win64, Abi};
use syntax::abi::{PlatformIntrinsic, RustIntrinsic, Rust, RustCall, Stdcall, Fastcall, System}; use syntax::abi::{PlatformIntrinsic, RustIntrinsic, Rust, RustCall, Stdcall, Fastcall, System};
@ -610,10 +610,12 @@ pub fn trans_rust_fn_with_foreign_abi<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
let t = tcx.node_id_to_type(id); let t = tcx.node_id_to_type(id);
let t = monomorphize::apply_param_substs(tcx, param_substs, &t); let t = monomorphize::apply_param_substs(tcx, param_substs, &t);
let ps = ccx.tcx().map.with_path(id, |path| { let path =
let abi = Some(hir_map::PathName(special_idents::clownshoe_abi.name)); tcx.map.def_path_from_id(id)
link::mangle(path.chain(abi), hash) .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 // 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. // normal Rust function. This will be the type of the wrappee fn.

View file

@ -44,7 +44,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
let csearch_result = let csearch_result =
csearch::maybe_get_item_ast( csearch::maybe_get_item_ast(
ccx.tcx(), fn_id, 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 { let inline_id = match csearch_result {
csearch::FoundAst::NotFound => { csearch::FoundAst::NotFound => {

View file

@ -110,6 +110,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
Some(&d) => d, None => 0 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 // Random cut-off -- code that needs to instantiate the same function
// recursively more than thirty times can probably safely be assumed // recursively more than thirty times can probably safely be assumed
// to be causing an infinite expansion. // to be causing an infinite expansion.
@ -128,9 +130,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>,
mono_ty.hash(&mut state); mono_ty.hash(&mut state);
hash = format!("h{}", state.finish()); hash = format!("h{}", state.finish());
ccx.tcx().map.with_path(fn_node_id, |path| { let path = ccx.tcx().map.def_path_from_id(fn_node_id);
exported_name(path, &hash[..]) exported_name(path, &hash[..])
})
}; };
debug!("monomorphize_fn mangled to {}", s); debug!("monomorphize_fn mangled to {}", s);

View file

@ -39,7 +39,7 @@ use rustc::metadata::cstore;
use rustc::metadata::csearch; use rustc::metadata::csearch;
use rustc::metadata::decoder; use rustc::metadata::decoder;
use rustc::middle::def; 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::subst::{self, ParamSpace, VecPerParamSpace};
use rustc::middle::ty; use rustc::middle::ty;
use rustc::middle::stability; use rustc::middle::stability;
@ -188,7 +188,7 @@ impl<'a, 'tcx> Clean<Crate> for visit_ast::RustdocVisitor<'a, 'tcx> {
attrs: child.attrs.clone(), attrs: child.attrs.clone(),
visibility: Some(hir::Public), visibility: Some(hir::Public),
stability: None, stability: None,
def_id: DefId::xxx_local(prim.to_node_id()), def_id: DefId::local(prim.to_def_index()),
inner: PrimitiveItem(prim), inner: PrimitiveItem(prim),
}); });
} }
@ -1559,8 +1559,9 @@ impl PrimitiveType {
/// Creates a rustdoc-specific node id for primitive types. /// Creates a rustdoc-specific node id for primitive types.
/// ///
/// These node ids are generally never used by the AST itself. /// These node ids are generally never used by the AST itself.
pub fn to_node_id(&self) -> ast::NodeId { pub fn to_def_index(&self) -> DefIndex {
u32::MAX - 1 - (*self as u32) let x = u32::MAX - 1 - (*self as u32);
DefIndex::new(x as usize)
} }
} }
@ -1744,7 +1745,7 @@ impl<'tcx> Clean<Item> for ty::FieldDefData<'tcx, 'static> {
let (name, attrs) = if self.name == unnamed_field.name { let (name, attrs) = if self.name == unnamed_field.name {
(None, None) (None, None)
} else { } else {
(Some(self.name), Some(attr_map.get(&self.did.xxx_node).unwrap())) (Some(self.name), Some(attr_map.get(&self.did).unwrap()))
}; };
Item { Item {

View file

@ -19,9 +19,8 @@ use std::fmt;
use std::iter::repeat; use std::iter::repeat;
use rustc::metadata::cstore::LOCAL_CRATE; 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::abi::Abi;
use syntax::ast;
use rustc_front::hir; use rustc_front::hir;
use clean; use clean;
@ -387,7 +386,7 @@ fn primitive_link(f: &mut fmt::Formatter,
Some(&cnum) => { Some(&cnum) => {
let path = &m.paths[&DefId { let path = &m.paths[&DefId {
krate: cnum, krate: cnum,
xxx_node: ast::CRATE_NODE_ID, index: CRATE_DEF_INDEX,
}]; }];
let loc = match m.extern_locations[&cnum] { let loc = match m.extern_locations[&cnum] {
(_, render::Remote(ref s)) => Some(s.to_string()), (_, render::Remote(ref s)) => Some(s.to_string()),

View file

@ -54,7 +54,7 @@ use externalfiles::ExternalHtml;
use serialize::json::{self, ToJson}; use serialize::json::{self, ToJson};
use syntax::{abi, ast, attr}; use syntax::{abi, ast, attr};
use rustc::metadata::cstore::LOCAL_CRATE; 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::util::nodemap::DefIdSet;
use rustc_front::hir; use rustc_front::hir;
@ -413,7 +413,7 @@ pub fn run(mut krate: clean::Crate,
for &(n, ref e) in &krate.externs { for &(n, ref e) in &krate.externs {
cache.extern_locations.insert(n, (e.name.clone(), cache.extern_locations.insert(n, (e.name.clone(),
extern_location(e, &cx.dst))); 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)); cache.paths.insert(did, (vec![e.name.to_string()], ItemType::Module));
} }
@ -1034,7 +1034,7 @@ impl DocFolder for Cache {
ref t => { ref t => {
match t.primitive_type() { match t.primitive_type() {
Some(prim) => { 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); self.parent_stack.push(did);
true true
} }
@ -1079,8 +1079,8 @@ impl DocFolder for Cache {
ref t => { ref t => {
t.primitive_type().and_then(|t| { t.primitive_type().and_then(|t| {
self.primitive_locations.get(&t).map(|n| { self.primitive_locations.get(&t).map(|n| {
let id = t.to_node_id(); let id = t.to_def_index();
DefId { krate: *n, xxx_node: id } DefId { krate: *n, index: id }
}) })
}) })
} }
@ -1421,7 +1421,7 @@ impl<'a> Item<'a> {
root = root, root = root,
path = path[..path.len() - 1].join("/"), path = path[..path.len() - 1].join("/"),
file = item_path(self.item), file = item_path(self.item),
goto = self.item.def_id.xxx_node)) goto = self.item.def_id.index.as_usize()))
} }
} }
} }
@ -1481,7 +1481,7 @@ impl<'a> fmt::Display for Item<'a> {
Some(l) => { Some(l) => {
try!(write!(fmt, "<a id='src-{}' class='srclink' \ try!(write!(fmt, "<a id='src-{}' class='srclink' \
href='{}' title='{}'>[src]</a>", 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 => {} None => {}
} }
@ -2337,7 +2337,7 @@ fn render_deref_methods(w: &mut fmt::Formatter, cx: &Context, impl_: &Impl) -> f
_ => { _ => {
if let Some(prim) = target.primitive_type() { if let Some(prim) = target.primitive_type() {
if let Some(c) = cache().primitive_locations.get(&prim) { 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)); try!(render_assoc_items(w, cx, did, what));
} }
} }

View file

@ -167,13 +167,13 @@ impl fmt::Display for Ident {
impl Encodable for Ident { impl Encodable for Ident {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> { 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 { impl Decodable for Ident {
fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> { 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))))
} }
} }