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

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

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_index: usize = 0x2a;
pub const tag_items_closure_kind: usize = 0x2a;
// GAP 0x2b, 0x2c, 0x2d, 0x2e
pub const tag_items_closure_ty: usize = 0x2b;
pub const tag_index: usize = 0x2c;
pub const tag_def_key: usize = 0x2d;
// GAP 0x2e
pub const tag_meta_item_name_value: usize = 0x2f;
@ -137,8 +143,7 @@ enum_from_u32! {
tag_table_adjustments = 0x61,
tag_table_moves_map = 0x62,
tag_table_capture_map = 0x63,
tag_table_closure_tys = 0x64,
tag_table_closure_kinds = 0x65,
// GAP 0x64, 0x65
tag_table_upvar_capture_map = 0x66,
tag_table_capture_modes = 0x67,
// GAP 0x68
@ -162,12 +167,12 @@ pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only
// tag_lang_items
// - tag_lang_items_item
// - tag_lang_items_item_id: u32
// - tag_lang_items_item_node_id: u32
// - tag_lang_items_item_index: u32
pub const tag_lang_items: usize = 0x107; // top-level only
pub const tag_lang_items_item: usize = 0x73;
pub const tag_lang_items_item_id: usize = 0x74;
pub const tag_lang_items_item_node_id: usize = 0x75;
pub const tag_lang_items_item_index: usize = 0x75;
pub const tag_lang_items_missing: usize = 0x76;
pub const tag_item_unnamed_field: usize = 0x77;
@ -215,7 +220,7 @@ pub struct LinkMeta {
pub const tag_struct_fields: usize = 0x10d; // top-level only
pub const tag_struct_field: usize = 0x8a;
pub const tag_struct_field_id: usize = 0x8b;
// GAP 0x8b
pub const tag_attribute_is_sugared_doc: usize = 0x8c;

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -8,143 +8,95 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use middle::def_id::{DefId, DefIndex};
use rbml;
use rbml::writer::Encoder;
use std::io::{Cursor, Write};
use std::slice;
use std::u32;
use syntax::ast::NodeId;
#[derive(Copy, Clone, PartialEq, PartialOrd, Eq, Ord)]
pub struct IndexEntry {
pub node: NodeId,
pub pos: u64
}
#[derive(Debug)]
pub struct IndexArrayEntry {
bits: u32,
first_pos: u32
}
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[..];
/// }
/// As part of the metadata, we generate an index that stores, for
/// each DefIndex, the position of the corresponding RBML document (if
/// any). This is just a big `[u32]` slice, where an entry of
/// `u32::MAX` indicates that there is no RBML document. This little
/// struct just stores the offsets within the metadata of the start
/// and end of this slice. These are actually part of an RBML
/// document, but for looking things up in the metadata, we just
/// discard the RBML positioning and jump directly to the data.
pub struct Index {
position_start: usize,
index_start: 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);
data_start: usize,
data_end: usize,
}
impl Index {
fn lookup_index(&self, index: &[u32], i: u32) -> Option<IndexArrayEntry> {
let ix = (i as usize)*2;
if ix >= index.len() {
None
} else {
Some(IndexArrayEntry::decode_from(&index[ix..ix+2]))
}
}
fn item_from_pos(&self, positions: &[u32], pos: u32) -> u32 {
positions[pos as usize].to_be()
/// Given the RBML doc representing the index, save the offests
/// for later.
pub fn from_rbml(index: rbml::Doc) -> Index {
Index { data_start: index.start, data_end: index.end }
}
/// Given the metadata, extract out the offset of a particular
/// DefIndex (if any).
#[inline(never)]
pub fn lookup_item(&self, buf: &[u8], node: NodeId) -> Option<u32> {
let index = bytes_to_words(&buf[self.index_start..self.index_end]);
let positions = bytes_to_words(&buf[self.position_start..self.index_start]);
let (x, s) = (node / 32 as u32, node % 32 as u32);
let result = match self.lookup_index(index, x) {
Some(IndexArrayEntry { bits, first_pos }) => {
let bit = 1<<s;
if bits & bit == 0 {
pub fn lookup_item(&self, bytes: &[u8], def_index: DefIndex) -> Option<u32> {
let words = bytes_to_words(&bytes[self.data_start..self.data_end]);
let index = def_index.as_usize();
debug!("lookup_item: index={:?} words.len={:?}",
index, words.len());
let position = u32::from_be(words[index]);
if position == u32::MAX {
debug!("lookup_item: position=u32::MAX");
None
} else {
let prev_nodes_for_entry = (bits&(bit-1)).count_ones();
Some(self.item_from_pos(
positions,
first_pos+prev_nodes_for_entry))
debug!("lookup_item: position={:?}", position);
Some(position)
}
}
None => None // trailing zero
};
debug!("lookup_item({:?}) = {:?}", node, result);
result
}
/// 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]
}
}
pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self {
let buf = bytes_to_words(&buf[start..end]);
let position_count = buf[0].to_be() as usize;
let position_len = position_count*4;
info!("loaded index - position: {}-{}-{}", start, start+position_len, end);
debug!("index contents are {:?}",
buf.iter().map(|b| format!("{:08x}", b)).collect::<Vec<_>>().concat());
assert!(end-4-start >= position_len);
assert_eq!((end-4-start-position_len)%8, 0);
Index {
position_start: start+4,
index_start: start+position_len+4,
index_end: end
pub fn record(&mut self, def_id: DefId, encoder: &mut Encoder) {
assert!(def_id.is_local());
self.record_index(def_id.index, encoder)
}
pub fn record_index(&mut self, item: DefIndex, encoder: &mut Encoder) {
let item = item.as_usize();
let position = encoder.mark_stable_position();
assert!(position < (u32::MAX as u64));
let position = position as u32;
assert!(self.positions[item] == u32::MAX,
"recorded position for item {:?} twice, first at {:?} and now at {:?}",
item, self.positions[item], position);
self.positions[item] = position;
}
pub fn write_index(&self, buf: &mut Cursor<Vec<u8>>) {
for &position in &self.positions {
write_be_u32(buf, position);
}
}
}
@ -162,47 +114,3 @@ fn bytes_to_words(b: &[u8]) -> &[u32] {
assert!(b.len() % 4 == 0);
unsafe { slice::from_raw_parts(b.as_ptr() as *const u32, b.len()/4) }
}
#[test]
fn test_index() {
let entries = vec![
IndexEntry { node: 0, pos: 17 },
IndexEntry { node: 31, pos: 29 },
IndexEntry { node: 32, pos: 1175 },
IndexEntry { node: 191, pos: 21 },
IndexEntry { node: 128, pos: 34 },
IndexEntry { node: 145, pos: 70 },
IndexEntry { node: 305, pos: 93214 },
IndexEntry { node: 138, pos: 64 },
IndexEntry { node: 129, pos: 53 },
IndexEntry { node: 192, pos: 33334 },
IndexEntry { node: 200, pos: 80123 },
];
let mut c = Cursor::new(vec![]);
write_index(entries.clone(), &mut c);
let mut buf = c.into_inner();
let expected: &[u8] = &[
0, 0, 0, 11, // # entries
// values:
0,0,0,17, 0,0,0,29, 0,0,4,151, 0,0,0,34,
0,0,0,53, 0,0,0,64, 0,0,0,70, 0,0,0,21,
0,0,130,54, 0,1,56,251, 0,1,108,30,
// index:
128,0,0,1,0,0,0,0, 0,0,0,1,0,0,0,2,
0,0,0,0,0,0,0,3, 0,0,0,0,0,0,0,3,
0,2,4,3,0,0,0,3, 128,0,0,0,0,0,0,7,
0,0,1,1,0,0,0,8, 0,0,0,0,0,0,0,10,
0,0,0,0,0,0,0,10, 0,2,0,0,0,0,0,10
];
assert_eq!(buf, expected);
// insert some junk padding
for i in 0..17 { buf.insert(0, i); buf.push(i) }
let index = Index::from_buf(&buf, 17, buf.len()-17);
// test round-trip
for i in 0..4096 {
assert_eq!(index.lookup_item(&buf, i),
entries.iter().find(|e| e.node == i).map(|n| n.pos as u32));
}
}

View file

@ -16,11 +16,9 @@
#![allow(non_camel_case_types)]
pub use self::DefIdSource::*;
use rustc_front::hir;
use middle::def_id::DefId;
use middle::def_id::{DefId, DefIndex};
use middle::region;
use middle::subst;
use middle::subst::VecPerParamSpace;
@ -36,32 +34,7 @@ use syntax::parse::token;
// parse_from_str. Extra parameters are for converting to/from def_ids in the
// data buffer. Whatever format you choose should not contain pipe characters.
// Def id conversion: when we encounter def-ids, they have to be translated.
// For example, the crate number must be converted from the crate number used
// in the library we are reading from into the local crate numbers in use
// here. To perform this translation, the type decoder is supplied with a
// conversion function of type `conv_did`.
//
// Sometimes, particularly when inlining, the correct translation of the
// def-id will depend on where it originated from. Therefore, the conversion
// function is given an indicator of the source of the def-id. See
// astencode.rs for more information.
#[derive(Copy, Clone, Debug)]
pub enum DefIdSource {
// Identifies a struct, trait, enum, etc.
NominalType,
// Identifies a type alias (`type X = ...`).
TypeWithId,
// Identifies a region parameter (`fn foo<'X>() { ... }`).
RegionParameter,
// Identifies a closure
ClosureSource
}
pub type DefIdConvert<'a> = &'a mut FnMut(DefIdSource, DefId) -> DefId;
pub type DefIdConvert<'a> = &'a mut FnMut(DefId) -> DefId;
pub struct TyDecoder<'a, 'tcx: 'a> {
data: &'a [u8],
@ -183,7 +156,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
ty::BrAnon(id)
}
'[' => {
let def = self.parse_def(RegionParameter);
let def = self.parse_def();
let name = token::intern(&self.parse_str(']'));
ty::BrNamed(def, name)
}
@ -209,7 +182,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
'B' => {
assert_eq!(self.next(), '[');
let def_id = self.parse_def(NominalType);
let def_id = self.parse_def();
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
@ -309,7 +282,7 @@ impl<'a,'tcx> TyDecoder<'a,'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());
ty::TraitRef {def_id: def, substs: substs}
}
@ -338,7 +311,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
'c' => return tcx.types.char,
't' => {
assert_eq!(self.next(), '[');
let did = self.parse_def(NominalType);
let did = self.parse_def();
let substs = self.parse_substs();
assert_eq!(self.next(), ']');
let def = self.tcx.lookup_adt_def(did);
@ -385,7 +358,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
return tcx.mk_tup(params);
}
'F' => {
let def_id = self.parse_def(NominalType);
let def_id = self.parse_def();
return tcx.mk_fn(Some(def_id), tcx.mk_bare_fn(self.parse_bare_fn_ty()));
}
'G' => {
@ -427,13 +400,13 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
return tt;
}
'\"' => {
let _ = self.parse_def(TypeWithId);
let _ = self.parse_def();
let inner = self.parse_ty();
inner
}
'a' => {
assert_eq!(self.next(), '[');
let did = self.parse_def(NominalType);
let did = self.parse_def();
let substs = self.parse_substs();
assert_eq!(self.next(), ']');
let def = self.tcx.lookup_adt_def(did);
@ -441,7 +414,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
}
'k' => {
assert_eq!(self.next(), '[');
let did = self.parse_def(ClosureSource);
let did = self.parse_def();
let substs = self.parse_substs();
let mut tys = vec![];
while self.peek() != '.' {
@ -476,9 +449,9 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
ty::TypeAndMut { ty: self.parse_ty(), mutbl: m }
}
fn parse_def(&mut self, source: DefIdSource) -> DefId {
fn parse_def(&mut self) -> DefId {
let def_id = parse_defid(self.scan(|c| c == '|'));
return (self.conv_def_id)(source, def_id);
return (self.conv_def_id)(def_id);
}
fn parse_uint(&mut self) -> usize {
@ -581,7 +554,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
'p' => ty::Binder(self.parse_projection_predicate()).to_predicate(),
'w' => ty::Predicate::WellFormed(self.parse_ty()),
'O' => {
let def_id = self.parse_def(NominalType);
let def_id = self.parse_def();
assert_eq!(self.next(), '|');
ty::Predicate::ObjectSafe(def_id)
}
@ -601,12 +574,12 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
pub fn parse_type_param_def(&mut self) -> ty::TypeParameterDef<'tcx> {
let name = self.parse_name(':');
let def_id = self.parse_def(NominalType);
let def_id = self.parse_def();
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
assert_eq!(self.next(), '|');
let default_def_id = self.parse_def(NominalType);
let default_def_id = self.parse_def();
let default = self.parse_opt(|this| this.parse_ty());
let object_lifetime_default = self.parse_object_lifetime_default();
@ -623,7 +596,7 @@ impl<'a,'tcx> TyDecoder<'a,'tcx> {
pub fn parse_region_param_def(&mut self) -> ty::RegionParameterDef {
let name = self.parse_name(':');
let def_id = self.parse_def(NominalType);
let def_id = self.parse_def();
let space = self.parse_param_space();
assert_eq!(self.next(), '|');
let index = self.parse_u32();
@ -731,11 +704,12 @@ fn parse_defid(buf: &[u8]) -> DefId {
let def_num = match str::from_utf8(def_part).ok().and_then(|s| {
s.parse::<usize>().ok()
}) {
Some(dn) => dn as ast::NodeId,
Some(dn) => dn,
None => panic!("internal error: parse_defid: id expected, found {:?}",
def_part)
};
DefId { krate: crate_num, xxx_node: def_num }
let index = DefIndex::new(def_num);
DefId { krate: crate_num, index: index }
}
fn parse_unsafety(c: char) -> hir::Unsafety {

View file

@ -19,14 +19,11 @@ use rustc_front::fold::Folder;
use metadata::common as c;
use metadata::cstore as cstore;
use metadata::cstore::LOCAL_CRATE;
use session::Session;
use metadata::decoder;
use metadata::encoder as e;
use metadata::inline::{InlinedItem, InlinedItemRef};
use metadata::tydecode;
use metadata::tydecode::{DefIdSource, NominalType, TypeWithId};
use metadata::tydecode::{RegionParameter, ClosureSource};
use metadata::tyencode;
use middle::ty::adjustment;
use middle::ty::cast;
@ -73,10 +70,6 @@ trait tr {
fn tr(&self, dcx: &DecodeContext) -> Self;
}
trait tr_intern {
fn tr_intern(&self, dcx: &DecodeContext) -> DefId;
}
// ______________________________________________________________________
// Top-level methods.
@ -130,10 +123,12 @@ impl<'a, 'b, 'c, 'tcx> ast_map::FoldOps for &'a DecodeContext<'b, 'c, 'tcx> {
pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
tcx: &ty::ctxt<'tcx>,
path: Vec<ast_map::PathElem>,
def_path: ast_map::DefPath,
par_doc: rbml::Doc)
-> Result<&'tcx InlinedItem, Vec<ast_map::PathElem>> {
-> Result<&'tcx InlinedItem, (Vec<ast_map::PathElem>,
ast_map::DefPath)> {
match par_doc.opt_child(c::tag_ast) {
None => Err(path),
None => Err((path, def_path)),
Some(ast_doc) => {
let mut path_as_str = None;
debug!("> Decoding inlined fn: {:?}::?",
@ -154,7 +149,7 @@ pub fn decode_inlined_item<'tcx>(cdata: &cstore::crate_metadata,
last_filemap_index: Cell::new(0)
};
let raw_ii = decode_ast(ast_doc);
let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, raw_ii, dcx);
let ii = ast_map::map_decoded_item(&dcx.tcx.map, path, def_path, raw_ii, dcx);
let name = match *ii {
InlinedItem::Item(ref i) => i.name,
@ -214,24 +209,10 @@ impl<'a, 'b, 'tcx> DecodeContext<'a, 'b, 'tcx> {
/// be inlined. Note that even when the inlined function is referencing itself recursively, we
/// would want `tr_def_id` for that reference--- conceptually the function calls the original,
/// non-inlined version, and trans deals with linking that recursive call to the inlined copy.
///
/// However, there are a *few* cases where def-ids are used but we know that the thing being
/// referenced is in fact *internal* to the item being inlined. In those cases, you should use
/// `tr_intern_def_id()` below.
pub fn tr_def_id(&self, did: DefId) -> DefId {
decoder::translate_def_id(self.cdata, did)
}
/// Translates an INTERNAL def-id, meaning a def-id that is
/// known to refer to some part of the item currently being
/// inlined. In that case, we want to convert the def-id to
/// refer to the current crate and to the new, inlined node-id.
pub fn tr_intern_def_id(&self, did: DefId) -> DefId {
assert_eq!(did.krate, LOCAL_CRATE);
DefId { krate: LOCAL_CRATE, xxx_node: self.tr_id(did.xxx_node) }
}
/// Translates a `Span` from an extern crate to the corresponding `Span`
/// within the local crate's codemap. `creader::import_codemap()` will
/// already have allocated any additionally needed FileMaps in the local
@ -290,12 +271,6 @@ 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 {
fn tr(&self, dcx: &DecodeContext) -> DefId {
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) {
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> {
fn emit_closure_type<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>,
closure_type: &ty::ClosureTy<'tcx>);
fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region);
fn emit_ty<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, ty: Ty<'tcx>);
fn emit_tys<'a>(&mut self, ecx: &e::EncodeContext<'a, 'tcx>, tys: &[Ty<'tcx>]);
@ -662,14 +631,6 @@ trait rbml_writer_helpers<'tcx> {
}
impl<'a, 'tcx> rbml_writer_helpers<'tcx> for Encoder<'a> {
fn emit_closure_type<'b>(&mut self,
ecx: &e::EncodeContext<'b, 'tcx>,
closure_type: &ty::ClosureTy<'tcx>) {
self.emit_opaque(|this| {
Ok(e::write_closure_type(ecx, this, closure_type))
});
}
fn emit_region(&mut self, ecx: &e::EncodeContext, r: ty::Region) {
self.emit_opaque(|this| Ok(e::write_region(ecx, this, r)));
}
@ -1005,24 +966,6 @@ fn encode_side_tables_for_id(ecx: &e::EncodeContext,
})
}
if let Some(def_id) = opt_def_id {
if let Some(closure_type) = tcx.tables.borrow().closure_tys.get(&def_id) {
rbml_w.tag(c::tag_table_closure_tys, |rbml_w| {
rbml_w.id(id);
rbml_w.emit_closure_type(ecx, closure_type);
})
}
}
if let Some(def_id) = opt_def_id {
if let Some(closure_kind) = tcx.tables.borrow().closure_kinds.get(&def_id) {
rbml_w.tag(c::tag_table_closure_kinds, |rbml_w| {
rbml_w.id(id);
encode_closure_kind(rbml_w, *closure_kind)
})
}
}
if let Some(cast_kind) = tcx.cast_kinds.borrow().get(&id) {
rbml_w.tag(c::tag_table_cast_kinds, |rbml_w| {
rbml_w.id(id);
@ -1080,17 +1023,12 @@ trait rbml_decoder_decoder_helpers<'tcx> {
-> adjustment::AutoAdjustment<'tcx>;
fn read_cast_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> cast::CastKind;
fn read_closure_kind<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::ClosureKind;
fn read_closure_ty<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> ty::ClosureTy<'tcx>;
fn read_auto_deref_ref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> adjustment::AutoDerefRef<'tcx>;
fn read_autoref<'a, 'b>(&mut self, dcx: &DecodeContext<'a, 'b, 'tcx>)
-> adjustment::AutoRef<'tcx>;
fn convert_def_id(&mut self,
dcx: &DecodeContext,
source: DefIdSource,
did: DefId)
-> DefId;
@ -1114,7 +1052,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
self.read_opaque(|_, doc| {
Ok(
tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc,
&mut |_, id| decoder::translate_def_id(cdata, id))
&mut |id| decoder::translate_def_id(cdata, id))
.parse_ty())
}).unwrap()
}
@ -1136,7 +1074,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
self.read_opaque(|_, doc| {
Ok(
tydecode::TyDecoder::with_doc(tcx, cdata.cnum, doc,
&mut |_, id| decoder::translate_def_id(cdata, id))
&mut |id| decoder::translate_def_id(cdata, id))
.parse_substs())
}).unwrap()
}
@ -1149,7 +1087,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
Ok(op(
&mut tydecode::TyDecoder::with_doc(
dcx.tcx, dcx.cdata.cnum, doc,
&mut |s, a| this.convert_def_id(dcx, s, a))))
&mut |a| this.convert_def_id(dcx, a))))
}).unwrap();
fn type_string(doc: rbml::Doc) -> String {
@ -1238,7 +1176,7 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
-> subst::Substs<'tcx> {
self.read_opaque(|this, doc| {
Ok(tydecode::TyDecoder::with_doc(dcx.tcx, dcx.cdata.cnum, doc,
&mut |s, a| this.convert_def_id(dcx, s, a))
&mut |a| this.convert_def_id(dcx, a))
.parse_substs())
}).unwrap()
}
@ -1345,18 +1283,6 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
Decodable::decode(self).unwrap()
}
fn read_closure_kind<'b, 'c>(&mut self, _dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::ClosureKind
{
Decodable::decode(self).unwrap()
}
fn read_closure_ty<'b, 'c>(&mut self, dcx: &DecodeContext<'b, 'c, 'tcx>)
-> ty::ClosureTy<'tcx>
{
self.read_ty_encoded(dcx, |decoder| decoder.parse_closure_ty())
}
/// Converts a def-id that appears in a type. The correct
/// translation will depend on what kind of def-id this is.
/// This is a subtle point: type definitions are not
@ -1391,14 +1317,10 @@ impl<'a, 'tcx> rbml_decoder_decoder_helpers<'tcx> for reader::Decoder<'a> {
/// def-ids so that all these distinctions were unnecessary.
fn convert_def_id(&mut self,
dcx: &DecodeContext,
source: tydecode::DefIdSource,
did: DefId)
-> DefId {
let r = match source {
NominalType | TypeWithId | RegionParameter => dcx.tr_def_id(did),
ClosureSource => dcx.tr_intern_def_id(did)
};
debug!("convert_def_id(source={:?}, did={:?})={:?}", source, did, r);
let r = dcx.tr_def_id(did);
debug!("convert_def_id(did={:?})={:?}", did, r);
return r;
}
}
@ -1485,20 +1407,6 @@ fn decode_side_tables(dcx: &DecodeContext,
val_dsr.read_auto_adjustment(dcx);
dcx.tcx.tables.borrow_mut().adjustments.insert(id, adj);
}
c::tag_table_closure_tys => {
let closure_ty =
val_dsr.read_closure_ty(dcx);
dcx.tcx.tables.borrow_mut().closure_tys.insert(
dcx.tcx.map.local_def_id(id),
closure_ty);
}
c::tag_table_closure_kinds => {
let closure_kind =
val_dsr.read_closure_kind(dcx);
dcx.tcx.tables.borrow_mut().closure_kinds.insert(
dcx.tcx.map.local_def_id(id),
closure_kind);
}
c::tag_table_cast_kinds => {
let cast_kind =
val_dsr.read_cast_kind(dcx);

View file

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

View file

@ -10,20 +10,53 @@
use metadata::cstore::LOCAL_CRATE;
use middle::ty;
use syntax::ast::{CrateNum, NodeId};
use syntax::ast::CrateNum;
use std::fmt;
use std::u32;
/// A DefIndex is an index into the hir-map for a crate, identifying a
/// particular definition. It should really be considered an interned
/// shorthand for a particular DefPath.
#[derive(Clone, Debug, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
RustcDecodable, Hash, Copy)]
pub struct DefIndex(u32);
impl DefIndex {
pub fn new(x: usize) -> DefIndex {
assert!(x < (u32::MAX as usize));
DefIndex(x as u32)
}
pub fn from_u32(x: u32) -> DefIndex {
DefIndex(x)
}
pub fn as_usize(&self) -> usize {
self.0 as usize
}
pub fn as_u32(&self) -> u32 {
self.0
}
}
/// The crate root is always assigned index 0 by the AST Map code,
/// thanks to `NodeCollector::new`.
pub const CRATE_DEF_INDEX: DefIndex = DefIndex(0);
/// A DefId identifies a particular *definition*, by combining a crate
/// index and a def index.
#[derive(Clone, Eq, Ord, PartialOrd, PartialEq, RustcEncodable,
RustcDecodable, Hash, Copy)]
pub struct DefId {
pub krate: CrateNum,
pub xxx_node: NodeId,
pub index: DefIndex,
}
impl fmt::Debug for DefId {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
try!(write!(f, "DefId {{ krate: {}, node: {}",
self.krate, self.xxx_node));
try!(write!(f, "DefId {{ krate: {:?}, node: {:?}",
self.krate, self.index));
// Unfortunately, there seems to be no way to attempt to print
// a path for a def-id, so I'll just make a best effort for now
@ -41,8 +74,8 @@ impl fmt::Debug for DefId {
impl DefId {
pub fn xxx_local(id: NodeId) -> DefId {
DefId { krate: LOCAL_CRATE, xxx_node: id }
pub fn local(index: DefIndex) -> DefId {
DefId { krate: LOCAL_CRATE, index: index }
}
pub fn is_local(&self) -> bool {

View file

@ -276,7 +276,7 @@ enum PassArgs {
}
impl<'d,'t,'a,'tcx> ExprUseVisitor<'d,'t,'a,'tcx> {
pub fn new(delegate: &'d mut Delegate<'tcx>,
pub fn new(delegate: &'d mut (Delegate<'tcx>),
typer: &'t infer::InferCtxt<'a, 'tcx>)
-> ExprUseVisitor<'d,'t,'a,'tcx> where 'tcx:'a
{

View file

@ -1455,7 +1455,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
def_id: DefId)
-> Option<ty::ClosureKind>
{
if def_id.is_local() {
self.tables.borrow().closure_kinds.get(&def_id).cloned()
} else {
// During typeck, ALL closures are local. But afterwards,
// during trans, we see closure ids from other traits.
// That may require loading the closure data out of the
// cstore.
Some(ty::Tables::closure_kind(&self.tables, self.tcx, def_id))
}
}
pub fn closure_type(&self,
@ -1463,12 +1471,11 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> {
substs: &ty::ClosureSubsts<'tcx>)
-> ty::ClosureTy<'tcx>
{
let closure_ty = self.tables
.borrow()
.closure_tys
.get(&def_id)
.unwrap()
.subst(self.tcx, &substs.func_substs);
let closure_ty =
ty::Tables::closure_type(self.tables,
self.tcx,
def_id,
substs);
if self.normalize {
normalize_associated_type(&self.tcx, &closure_ty)

View file

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

View file

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

View file

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

View file

@ -16,6 +16,7 @@
use front::map as ast_map;
use session::Session;
use lint;
use metadata::csearch;
use middle;
use middle::def::DefMap;
use middle::def_id::DefId;
@ -134,6 +135,40 @@ impl<'tcx> Tables<'tcx> {
closure_kinds: DefIdMap(),
}
}
pub fn closure_kind(this: &RefCell<Self>,
tcx: &ty::ctxt<'tcx>,
def_id: DefId)
-> ty::ClosureKind {
// If this is a local def-id, it should be inserted into the
// tables by typeck; else, it will be retreived from
// the external crate metadata.
if let Some(&kind) = this.borrow().closure_kinds.get(&def_id) {
return kind;
}
let kind = csearch::closure_kind(tcx, def_id);
this.borrow_mut().closure_kinds.insert(def_id, kind);
kind
}
pub fn closure_type(this: &RefCell<Self>,
tcx: &ty::ctxt<'tcx>,
def_id: DefId,
substs: &ClosureSubsts<'tcx>)
-> ty::ClosureTy<'tcx>
{
// If this is a local def-id, it should be inserted into the
// tables by typeck; else, it will be retreived from
// the external crate metadata.
if let Some(ty) = this.borrow().closure_tys.get(&def_id) {
return ty.subst(tcx, &substs.func_substs);
}
let ty = csearch::closure_ty(tcx, def_id);
this.borrow_mut().closure_tys.insert(def_id, ty.clone());
ty.subst(tcx, &substs.func_substs)
}
}
impl<'tcx> CommonTypes<'tcx> {
@ -336,19 +371,8 @@ pub struct ctxt<'tcx> {
/// constitute it.
pub fragment_infos: RefCell<DefIdMap<Vec<ty::FragmentInfo>>>,
}
impl<'tcx> ctxt<'tcx> {
pub fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind {
*self.tables.borrow().closure_kinds.get(&def_id).unwrap()
}
pub fn closure_type(&self,
def_id: DefId,
substs: &ClosureSubsts<'tcx>)
-> ty::ClosureTy<'tcx>
{
self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, &substs.func_substs)
}
pub fn type_parameter_def(&self,
node_id: NodeId)
-> ty::TypeParameterDef<'tcx>

View file

@ -2263,6 +2263,14 @@ impl<'tcx> ctxt<'tcx> {
self.with_path(id, |path| ast_map::path_to_string(path))
}
pub fn def_path(&self, id: DefId) -> ast_map::DefPath {
if id.is_local() {
self.map.def_path(id)
} else {
csearch::def_path(self, id)
}
}
pub fn with_path<T, F>(&self, id: DefId, f: F) -> T where
F: FnOnce(ast_map::PathElems) -> T,
{
@ -2480,6 +2488,18 @@ impl<'tcx> ctxt<'tcx> {
def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID);
}
pub fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind {
Tables::closure_kind(&self.tables, self, def_id)
}
pub fn closure_type(&self,
def_id: DefId,
substs: &ClosureSubsts<'tcx>)
-> ty::ClosureTy<'tcx>
{
Tables::closure_type(&self.tables, self, def_id, substs)
}
/// Given the def_id of an impl, return the def_id of the trait it implements.
/// If it implements no trait, return `None`.
pub fn trait_id_of_impl(&self, def_id: DefId) -> Option<DefId> {
@ -2800,3 +2820,4 @@ pub trait HasTypeFlags {
!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)
};
h.as_str().hash(state);
did.xxx_node.hash(state);
did.index.hash(state);
};
let mt = |state: &mut SipHasher, mt: TypeAndMut| {
mt.mutbl.hash(state);

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

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

View file

@ -346,7 +346,7 @@ impl<'tcx> TypeMap<'tcx> {
output.push_str(crate_hash.as_str());
output.push_str("/");
output.push_str(&format!("{:x}", def_id.xxx_node));
output.push_str(&format!("{:x}", def_id.index.as_usize()));
// Maybe check that there is no self type here.

View file

@ -1195,14 +1195,23 @@ fn trans_rvalue_dps_unadjusted<'blk, 'tcx>(bcx: Block<'blk, 'tcx>,
SaveIn(lldest) => closure::Dest::SaveIn(bcx, lldest),
Ignore => closure::Dest::Ignore(bcx.ccx())
};
let substs = match expr_ty(bcx, expr).sty {
ty::TyClosure(_, ref substs) => substs,
// NB. To get the id of the closure, we don't use
// `local_def_id(id)`, but rather we extract the closure
// def-id from the expr's type. This is because this may
// be an inlined expression from another crate, and we
// want to get the ORIGINAL closure def-id, since that is
// the key we need to find the closure-kind and
// closure-type etc.
let (def_id, substs) = match expr_ty(bcx, expr).sty {
ty::TyClosure(def_id, ref substs) => (def_id, substs),
ref t =>
bcx.tcx().sess.span_bug(
expr.span,
&format!("closure expr without closure type: {:?}", t)),
};
closure::trans_closure_expr(dest, decl, body, expr.id, substs).unwrap_or(bcx)
closure::trans_closure_expr(dest, decl, body, expr.id, def_id, substs).unwrap_or(bcx)
}
hir::ExprCall(ref f, ref args) => {
if bcx.tcx().is_method_call(expr.id) {

View file

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

View file

@ -44,7 +44,7 @@ fn instantiate_inline(ccx: &CrateContext, fn_id: DefId)
let csearch_result =
csearch::maybe_get_item_ast(
ccx.tcx(), fn_id,
Box::new(|a,b,c,d| astencode::decode_inlined_item(a, b, c, d)));
Box::new(|a,b,c,d,e| astencode::decode_inlined_item(a, b, c, d,e)));
let inline_id = match csearch_result {
csearch::FoundAst::NotFound => {

View file

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

View file

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

View file

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

View file

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

View file

@ -167,13 +167,13 @@ impl fmt::Display for Ident {
impl Encodable for Ident {
fn encode<S: Encoder>(&self, s: &mut S) -> Result<(), S::Error> {
s.emit_str(&self.name.as_str())
self.name.encode(s)
}
}
impl Decodable for Ident {
fn decode<D: Decoder>(d: &mut D) -> Result<Ident, D::Error> {
Ok(str_to_ident(&try!(d.read_str())[..]))
Ok(Ident::with_empty_ctxt(try!(Name::decode(d))))
}
}