From 01f32ace0302373fb69ef9e2d0e21cc841981eba Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Thu, 17 Sep 2015 14:29:59 -0400 Subject: [PATCH] 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. --- src/librustc/front/map/collector.rs | 163 +++++++---- src/librustc/front/map/definitions.rs | 263 ++++++++++++++++++ src/librustc/front/map/mod.rs | 68 +++-- src/librustc/metadata/common.rs | 19 +- src/librustc/metadata/creader.rs | 7 +- src/librustc/metadata/csearch.rs | 103 ++++--- src/librustc/metadata/cstore.rs | 18 ++ src/librustc/metadata/decoder.rs | 222 +++++++++------ src/librustc/metadata/encoder.rs | 248 +++++++++-------- src/librustc/metadata/index.rs | 224 +++++---------- src/librustc/metadata/tydecode.rs | 64 ++--- src/librustc/middle/astencode.rs | 114 +------- src/librustc/middle/const_eval.rs | 6 +- src/librustc/middle/def_id.rs | 45 ++- src/librustc/middle/expr_use_visitor.rs | 2 +- src/librustc/middle/infer/mod.rs | 21 +- src/librustc/middle/lang_items.rs | 4 +- src/librustc/middle/stability.rs | 4 +- src/librustc/middle/traits/select.rs | 7 +- src/librustc/middle/ty/context.rs | 48 +++- src/librustc/middle/ty/mod.rs | 21 ++ src/librustc/middle/ty/util.rs | 2 +- src/librustc/util/ppaux.rs | 2 +- src/librustc_lint/builtin.rs | 22 +- src/librustc_resolve/build_reduced_graph.rs | 4 +- src/librustc_trans/back/link.rs | 29 +- src/librustc_trans/save/recorder.rs | 37 ++- src/librustc_trans/trans/base.rs | 9 +- src/librustc_trans/trans/closure.rs | 35 +-- src/librustc_trans/trans/common.rs | 7 +- src/librustc_trans/trans/consts.rs | 4 +- .../trans/debuginfo/metadata.rs | 2 +- src/librustc_trans/trans/expr.rs | 15 +- src/librustc_trans/trans/foreign.rs | 12 +- src/librustc_trans/trans/inline.rs | 2 +- src/librustc_trans/trans/monomorphize.rs | 7 +- src/librustdoc/clean/mod.rs | 11 +- src/librustdoc/html/format.rs | 5 +- src/librustdoc/html/render.rs | 16 +- src/libsyntax/ast.rs | 4 +- 40 files changed, 1119 insertions(+), 777 deletions(-) create mode 100644 src/librustc/front/map/definitions.rs diff --git a/src/librustc/front/map/collector.rs b/src/librustc/front/map/collector.rs index a252992812ebb..5f3148c7c33c5 100644 --- a/src/librustc/front/map/collector.rs +++ b/src/librustc/front/map/collector.rs @@ -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>, - 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>, - 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 { + 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, + 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)); } } diff --git a/src/librustc/front/map/definitions.rs b/src/librustc/front/map/definitions.rs new file mode 100644 index 0000000000000..c1eb5f1f11845 --- /dev/null +++ b/src/librustc/front/map/definitions.rs @@ -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 or the MIT license +// , 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, + key_map: FnvHashMap, + node_map: NodeMap, +} + +/// 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, + + /// 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; + +#[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 { + self.node_map.get(&node).cloned() + } + + pub fn opt_local_def_id(&self, node: ast::NodeId) -> Option { + self.opt_def_index(node).map(DefId::local) + } + + pub fn as_local_node_id(&self, def_id: DefId) -> Option { + 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, + 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("") + } + + // note that this does not show up in user printouts + CrateRoot => { + InternedString::new("") + } + + // note that this does not show up in user printouts + InlinedRoot(_) => { + InternedString::new("") + } + + Misc => { + InternedString::new("?") + } + + Impl => { + InternedString::new("") + } + + ClosureExpr => { + InternedString::new("") + } + + StructCtor => { + InternedString::new("") + } + + Initializer => { + InternedString::new("") + } + } + } + + pub fn to_string(&self) -> String { + self.as_interned_str().to_string() + } +} + +pub fn make_def_path(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 +} diff --git a/src/librustc/front/map/mod.rs b/src/librustc/front/map/mod.rs index 0486fd3a0d1bb..aba6429abaefd 100644 --- a/src/librustc/front/map/mod.rs +++ b/src/librustc/front/map/mod.rs @@ -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>>, - definitions_map: RefCell, + definitions: RefCell, } 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 { - 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 { - 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 Folder for IdAndSpanUpdater { 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, + def_path: DefPath, ii: InlinedItem, fold_ops: F) -> &'ast InlinedItem { @@ -845,14 +861,16 @@ pub fn map_decoded_item<'ast, F: FoldOps>(map: &Map<'ast>, let ii_parent_id = fld.new_id(DUMMY_NODE_ID); let mut collector = - NodeCollector::extend(ii_parent, - ii_parent_id, - mem::replace(&mut *map.map.borrow_mut(), vec![]), - mem::replace(&mut *map.definitions_map.borrow_mut(), NodeSet())); + NodeCollector::extend( + ii_parent, + ii_parent_id, + def_path, + mem::replace(&mut *map.map.borrow_mut(), vec![]), + mem::replace(&mut *map.definitions.borrow_mut(), Definitions::new())); ii_parent.ii.visit(&mut collector); *map.map.borrow_mut() = collector.map; - *map.definitions_map.borrow_mut() = collector.definitions_map; + *map.definitions.borrow_mut() = collector.definitions; &ii_parent.ii } diff --git a/src/librustc/metadata/common.rs b/src/librustc/metadata/common.rs index a6cbb4ec50490..7b8ad78da74dc 100644 --- a/src/librustc/metadata/common.rs +++ b/src/librustc/metadata/common.rs @@ -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; diff --git a/src/librustc/metadata/creader.rs b/src/librustc/metadata/creader.rs index 04f164c296d2e..fe4a909a08516 100644 --- a/src/librustc/metadata/creader.rs +++ b/src/librustc/metadata/creader.rs @@ -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) }); diff --git a/src/librustc/metadata/csearch.rs b/src/librustc/metadata/csearch.rs index 70a969e4d8221..402aa52612e87 100644 --- a/src/librustc/metadata/csearch.rs +++ b/src/librustc/metadata/csearch.rs @@ -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(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(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(cstore: &cstore::CStore, pub fn get_item_path(tcx: &ty::ctxt, def: DefId) -> Vec { 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 { 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 { 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 { 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>> { 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>> { 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 { 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 > { 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 { 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 { 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> { +pub fn get_struct_field_attrs(cstore: &cstore::CStore, def: DefId) + -> FnvHashMap> { 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> { 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(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(cstore: &cstore::CStore, @@ -300,7 +300,7 @@ pub fn get_trait_of_item(cstore: &cstore::CStore, tcx: &ty::ctxt) -> Option { 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 { 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 { 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 { 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 { 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() +} + diff --git a/src/librustc/metadata/cstore.rs b/src/librustc/metadata/cstore.rs index 915027041bc44..48676a2a1b48a 100644 --- a/src/librustc/metadata/cstore.rs +++ b/src/librustc/metadata/cstore.rs @@ -59,6 +59,7 @@ pub struct ImportedFileMap { pub struct crate_metadata { pub name: String, pub local_path: RefCell>, + pub local_def_path: RefCell, pub data: MetadataBlob, pub cnum_map: RefCell, 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") diff --git a/src/librustc/metadata/decoder.rs b/src/librustc/metadata/decoder.rs index 8ce31e533de82..58e87f1910a68 100644 --- a/src/librustc/metadata/decoder.rs +++ b/src/librustc/metadata/decoder.rs @@ -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 { + fn get_item(&self, item_id: DefIndex) -> Option { 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 { @@ -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 { 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> { 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 { } 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 { +pub fn get_stability(cdata: Cmd, id: DefIndex) -> Option { 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 { }) } -pub fn get_repr_attrs(cdata: Cmd, id: ast::NodeId) -> Vec { +pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec { 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 { } pub fn get_impl_polarity<'tcx>(cdata: Cmd, - id: ast::NodeId) + id: DefIndex) -> Option { 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 { 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> { @@ -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(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(intr: Rc, }; // 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(intr: Rc, 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(intr: Rc, }; // 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(intr: Rc, /// Iterates over each child of the given item. pub fn each_child_of_item(intr: Rc, 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(intr: Rc, callback) } -pub fn get_item_path(cdata: Cmd, id: ast::NodeId) -> Vec { +pub fn get_item_path(cdata: Cmd, id: DefIndex) -> Vec { 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 FnMut(Cmd, &ty::ctxt<'tcx>, Vec, + hir_map::DefPath, rbml::Doc) - -> Result<&'tcx InlinedItem, Vec> + 'a>; + -> Result<&'tcx InlinedItem, (Vec, + 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 { 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, 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, 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, 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, } } -pub fn get_trait_item_def_ids(cdata: Cmd, id: ast::NodeId) +pub fn get_trait_item_def_ids(cdata: Cmd, id: DefIndex) -> Vec { 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, cdata: Cmd, - id: ast::NodeId, + id: DefIndex, tcx: &ty::ctxt<'tcx>) -> Vec>> { 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, pub fn get_associated_consts<'tcx>(intr: Rc, cdata: Cmd, - id: ast::NodeId, + id: DefIndex, tcx: &ty::ctxt<'tcx>) -> Vec>> { let item = cdata.lookup_item(id); @@ -960,13 +963,13 @@ pub fn get_associated_consts<'tcx>(intr: Rc, [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, } pub fn get_type_name_if_impl(cdata: Cmd, - node_id: ast::NodeId) -> Option { + node_id: DefIndex) -> Option { 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, cdata: Cmd, - node_id: ast::NodeId) + node_id: DefIndex) -> Option > { let item = cdata.lookup_item(node_id); if item_family(item) != Impl { @@ -1011,7 +1014,7 @@ pub fn get_methods_if_impl(intr: Rc, 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, /// 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 { 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 { // 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> { +pub fn get_struct_field_attrs(cdata: Cmd) -> FnvHashMap> { 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 { 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 { 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 { } pub fn each_inherent_implementation_for_type(cdata: Cmd, - id: ast::NodeId, + id: DefIndex, mut callback: F) where F: FnMut(DefId), { @@ -1277,7 +1280,7 @@ pub fn each_implementation_for_trait(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(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 { 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 { +pub fn get_plugin_registrar_fn(data: &[u8]) -> Option { 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(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 { +pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec { 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 { 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 { }).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) + }) +} + diff --git a/src/librustc/metadata/encoder.rs b/src/librustc/metadata/encoder.rs index 14e5e8b41ffbb..f637545e2e910 100644 --- a/src/librustc/metadata/encoder.rs +++ b/src/librustc/metadata/encoder.rs @@ -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) { + 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) { + 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, + 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, + 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) { - 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, + 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) { + 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) { + 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, + 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 { - 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) -{ +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>, 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(); diff --git a/src/librustc/metadata/index.rs b/src/librustc/metadata/index.rs index b02a9022a7a6e..c60b789a2f1bf 100644 --- a/src/librustc/metadata/index.rs +++ b/src/librustc/metadata/index.rs @@ -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 +/// As part of the metadata, we generate an index that stores, for +/// each DefIndex, the position of the corresponding RBML document (if +/// any). This is just a big `[u32]` slice, where an entry of +/// `u32::MAX` indicates that there is no RBML document. This little +/// struct just stores the offsets within the metadata of the start +/// and end of this slice. These are actually part of an RBML +/// document, but for looking things up in the metadata, we just +/// discard the RBML positioning and jump directly to the data. +pub struct Index { + data_start: usize, + data_end: usize, } -impl IndexArrayEntry { - fn encode_to(&self, b: &mut W) { - write_be_u32(b, self.bits); - write_be_u32(b, self.first_pos); +impl Index { + /// Given the RBML doc representing the index, save the offests + /// for later. + pub fn from_rbml(index: rbml::Doc) -> Index { + Index { data_start: index.start, data_end: index.end } } - fn decode_from(b: &[u32]) -> Self { - IndexArrayEntry { - bits: b[0].to_be(), - first_pos: b[1].to_be() + /// Given the metadata, extract out the offset of a particular + /// DefIndex (if any). + #[inline(never)] + pub fn lookup_item(&self, bytes: &[u8], def_index: DefIndex) -> Option { + let words = bytes_to_words(&bytes[self.data_start..self.data_end]); + let index = def_index.as_usize(); + + debug!("lookup_item: index={:?} words.len={:?}", + index, words.len()); + + let position = u32::from_be(words[index]); + if position == u32::MAX { + debug!("lookup_item: position=u32::MAX"); + None + } else { + debug!("lookup_item: position={:?}", position); + Some(position) } } } -/// The Item Index -/// -/// This index maps the NodeId of each item to its location in the -/// metadata. -/// -/// The index is a sparse bit-vector consisting of a index-array -/// and a position-array. Each entry in the index-array handles 32 nodes. -/// The first word is a bit-array consisting of the nodes that hold items, -/// the second is the index of the first of the items in the position-array. -/// If there is a large set of non-item trailing nodes, they can be omitted -/// from the index-array. -/// -/// The index is serialized as an array of big-endian 32-bit words. -/// The first word is the number of items in the position-array. -/// Then, for each item, its position in the metadata follows. -/// After that the index-array is stored. -/// -/// struct index { -/// u32 item_count; -/// u32 items[self.item_count]; -/// struct { u32 bits; u32 offset; } positions[..]; -/// } -pub struct Index { - position_start: usize, - index_start: usize, - index_end: usize, +/// While we are generating the metadata, we also track the position +/// of each DefIndex. It is not required that all definitions appear +/// in the metadata, nor that they are serialized in order, and +/// therefore we first allocate the vector here and fill it with +/// `u32::MAX`. Whenever an index is visited, we fill in the +/// appropriate spot by calling `record_position`. We should never +/// visit the same index twice. +pub struct IndexData { + positions: Vec, } -pub fn write_index(mut entries: Vec, buf: &mut Cursor>) { - assert!(entries.len() < u32::MAX as usize); - entries.sort(); - - let mut last_entry = IndexArrayEntry { bits: 0, first_pos: 0 }; - - write_be_u32(buf, entries.len() as u32); - for &IndexEntry { pos, .. } in &entries { - assert!(pos < u32::MAX as u64); - write_be_u32(buf, pos as u32); +impl IndexData { + pub fn new(max_index: usize) -> IndexData { + IndexData { + positions: vec![u32::MAX; max_index] + } } - let mut pos_in_index_array = 0; - for (i, &IndexEntry { node, .. }) in entries.iter().enumerate() { - let (x, s) = (node / 32 as u32, node % 32 as u32); - while x > pos_in_index_array { - pos_in_index_array += 1; - last_entry.encode_to(buf); - last_entry = IndexArrayEntry { bits: 0, first_pos: i as u32 }; - } - last_entry.bits |= 1< Option { - let ix = (i as usize)*2; - if ix >= index.len() { - None - } else { - Some(IndexArrayEntry::decode_from(&index[ix..ix+2])) - } - } + let position = encoder.mark_stable_position(); - fn item_from_pos(&self, positions: &[u32], pos: u32) -> u32 { - positions[pos as usize].to_be() - } + assert!(position < (u32::MAX as u64)); + let position = position as u32; - #[inline(never)] - pub fn lookup_item(&self, buf: &[u8], node: NodeId) -> Option { - 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< None // trailing zero - }; - debug!("lookup_item({:?}) = {:?}", node, result); - result + assert!(self.positions[item] == u32::MAX, + "recorded position for item {:?} twice, first at {:?} and now at {:?}", + item, self.positions[item], position); + + self.positions[item] = position; } - pub fn from_buf(buf: &[u8], start: usize, end: usize) -> Self { - let buf = bytes_to_words(&buf[start..end]); - let position_count = buf[0].to_be() as usize; - let position_len = position_count*4; - info!("loaded index - position: {}-{}-{}", start, start+position_len, end); - debug!("index contents are {:?}", - buf.iter().map(|b| format!("{:08x}", b)).collect::>().concat()); - assert!(end-4-start >= position_len); - assert_eq!((end-4-start-position_len)%8, 0); - Index { - position_start: start+4, - index_start: start+position_len+4, - index_end: end + pub fn write_index(&self, buf: &mut Cursor>) { + 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)); - } -} diff --git a/src/librustc/metadata/tydecode.rs b/src/librustc/metadata/tydecode.rs index f023049d78f61..4657323c1726d 100644 --- a/src/librustc/metadata/tydecode.rs +++ b/src/librustc/metadata/tydecode.rs @@ -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::().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 { diff --git a/src/librustc/middle/astencode.rs b/src/librustc/middle/astencode.rs index 02bd9951d341a..672ae5d3fb69c 100644 --- a/src/librustc/middle/astencode.rs +++ b/src/librustc/middle/astencode.rs @@ -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, + def_path: ast_map::DefPath, par_doc: rbml::Doc) - -> Result<&'tcx InlinedItem, Vec> { + -> Result<&'tcx InlinedItem, (Vec, + 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); diff --git a/src/librustc/middle/const_eval.rs b/src/librustc/middle/const_eval.rs index 00cfbf2dfe2c2..91d9f70aee9a7 100644 --- a/src/librustc/middle/const_eval.rs +++ b/src/librustc/middle/const_eval.rs @@ -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 diff --git a/src/librustc/middle/def_id.rs b/src/librustc/middle/def_id.rs index f8f3412c8bb2c..ed7a1d75a52e9 100644 --- a/src/librustc/middle/def_id.rs +++ b/src/librustc/middle/def_id.rs @@ -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 { diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index 512faa8f8b534..1eed7fb95a1f5 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -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 { diff --git a/src/librustc/middle/infer/mod.rs b/src/librustc/middle/infer/mod.rs index 3def56f94a181..3b44dc12ac197 100644 --- a/src/librustc/middle/infer/mod.rs +++ b/src/librustc/middle/infer/mod.rs @@ -1455,7 +1455,15 @@ impl<'a, 'tcx> InferCtxt<'a, 'tcx> { def_id: DefId) -> Option { - self.tables.borrow().closure_kinds.get(&def_id).cloned() + if def_id.is_local() { + self.tables.borrow().closure_kinds.get(&def_id).cloned() + } else { + // During typeck, ALL closures are local. But afterwards, + // during trans, we see closure ids from other traits. + // That may require loading the closure data out of the + // cstore. + Some(ty::Tables::closure_kind(&self.tables, self.tcx, def_id)) + } } pub fn closure_type(&self, @@ -1463,12 +1471,11 @@ 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) diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index 73313a5c257a6..03c75fc6cc370 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -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 }); diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index 73519b8f579d5..be227e620b881 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -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); } diff --git a/src/librustc/middle/traits/select.rs b/src/librustc/middle/traits/select.rs index 5e12e77435a12..60f6cffa346af 100644 --- a/src/librustc/middle/traits/select.rs +++ b/src/librustc/middle/traits/select.rs @@ -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() } diff --git a/src/librustc/middle/ty/context.rs b/src/librustc/middle/ty/context.rs index 57f04af2ba913..906ff5b2656e7 100644 --- a/src/librustc/middle/ty/context.rs +++ b/src/librustc/middle/ty/context.rs @@ -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, + 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, + 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>>, } -impl<'tcx> ctxt<'tcx> { - pub fn closure_kind(&self, def_id: DefId) -> ty::ClosureKind { - *self.tables.borrow().closure_kinds.get(&def_id).unwrap() - } - - pub fn closure_type(&self, - def_id: DefId, - substs: &ClosureSubsts<'tcx>) - -> ty::ClosureTy<'tcx> - { - self.tables.borrow().closure_tys.get(&def_id).unwrap().subst(self, &substs.func_substs) - } +impl<'tcx> ctxt<'tcx> { pub fn type_parameter_def(&self, node_id: NodeId) -> ty::TypeParameterDef<'tcx> diff --git a/src/librustc/middle/ty/mod.rs b/src/librustc/middle/ty/mod.rs index 1b334e3772244..315268fd0b626 100644 --- a/src/librustc/middle/ty/mod.rs +++ b/src/librustc/middle/ty/mod.rs @@ -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(&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 { @@ -2800,3 +2820,4 @@ pub trait HasTypeFlags { !self.has_type_flags(TypeFlags::HAS_LOCAL_NAMES) } } + diff --git a/src/librustc/middle/ty/util.rs b/src/librustc/middle/ty/util.rs index 2e6cc4faff8d0..b546438f392a0 100644 --- a/src/librustc/middle/ty/util.rs +++ b/src/librustc/middle/ty/util.rs @@ -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); diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index de356e54699c1..67ced5d32594d 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -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 { diff --git a/src/librustc_lint/builtin.rs b/src/librustc_lint/builtin.rs index d05b5b3e8606a..1df3c1609b890 100644 --- a/src/librustc_lint/builtin.rs +++ b/src/librustc_lint/builtin.rs @@ -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 } diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index c50cb5960b1ff..f74144565fc58 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -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, diff --git a/src/librustc_trans/back/link.rs b/src/librustc_trans/back/link.rs index 2e18b50a45cfe..eaa947150b04e 100644 --- a/src/librustc_trans/back/link.rs +++ b/src/librustc_trans/back/link.rs @@ -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>(path: PI, - hash: Option<&str>) -> String { +pub fn mangle>(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>(path: PI, } // First, connect each component with 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>(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) { diff --git a/src/librustc_trans/save/recorder.rs b/src/librustc_trans/save/recorder.rs index 769c124299899..f388f76c744e6 100644 --- a/src/librustc_trans/save/recorder.rs +++ b/src/librustc_trans/save/recorder.rs @@ -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, 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, trait_id: Option, 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, 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, declid: Option, 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)); } } diff --git a/src/librustc_trans/trans/base.rs b/src/librustc_trans/trans/base.rs index 61244e32c7d98..05b20ac3fb7d4 100644 --- a/src/librustc_trans/trans/base.rs +++ b/src/librustc_trans/trans/base.rs @@ -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, } } } - }) + } } } diff --git a/src/librustc_trans/trans/closure.rs b/src/librustc_trans/trans/closure.rs index 89724c38cb2c9..d3509c2f8133a 100644 --- a/src/librustc_trans/trans/closure.rs +++ b/src/librustc_trans/trans/closure.rs @@ -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> { + // (*) 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 = 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 diff --git a/src/librustc_trans/trans/common.rs b/src/librustc_trans/trans/common.rs index ba50bec2ecd91..d160465c619b9 100644 --- a/src/librustc_trans/trans/common.rs +++ b/src/librustc_trans/trans/common.rs @@ -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( diff --git a/src/librustc_trans/trans/consts.rs b/src/librustc_trans/trans/consts.rs index 6aa087cce56bd..a7bb4043e7d81 100644 --- a/src/librustc_trans/trans/consts.rs +++ b/src/librustc_trans/trans/consts.rs @@ -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( diff --git a/src/librustc_trans/trans/debuginfo/metadata.rs b/src/librustc_trans/trans/debuginfo/metadata.rs index 94c93a636a12c..a921bbbc43e30 100644 --- a/src/librustc_trans/trans/debuginfo/metadata.rs +++ b/src/librustc_trans/trans/debuginfo/metadata.rs @@ -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. diff --git a/src/librustc_trans/trans/expr.rs b/src/librustc_trans/trans/expr.rs index 476e05d50d20f..8d57c24ca90bb 100644 --- a/src/librustc_trans/trans/expr.rs +++ b/src/librustc_trans/trans/expr.rs @@ -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) { diff --git a/src/librustc_trans/trans/foreign.rs b/src/librustc_trans/trans/foreign.rs index 0310a8a604106..6b9f1559d3793 100644 --- a/src/librustc_trans/trans/foreign.rs +++ b/src/librustc_trans/trans/foreign.rs @@ -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. diff --git a/src/librustc_trans/trans/inline.rs b/src/librustc_trans/trans/inline.rs index 67abca78c6eb3..14b65bcb75504 100644 --- a/src/librustc_trans/trans/inline.rs +++ b/src/librustc_trans/trans/inline.rs @@ -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 => { diff --git a/src/librustc_trans/trans/monomorphize.rs b/src/librustc_trans/trans/monomorphize.rs index 39f3a29c785f4..33f798be85e87 100644 --- a/src/librustc_trans/trans/monomorphize.rs +++ b/src/librustc_trans/trans/monomorphize.rs @@ -110,6 +110,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, Some(&d) => d, None => 0 }; + debug!("monomorphic_fn: depth for fn_id={:?} is {:?}", fn_id, depth+1); + // Random cut-off -- code that needs to instantiate the same function // recursively more than thirty times can probably safely be assumed // to be causing an infinite expansion. @@ -128,9 +130,8 @@ pub fn monomorphic_fn<'a, 'tcx>(ccx: &CrateContext<'a, 'tcx>, mono_ty.hash(&mut state); hash = format!("h{}", state.finish()); - ccx.tcx().map.with_path(fn_node_id, |path| { - exported_name(path, &hash[..]) - }) + let path = ccx.tcx().map.def_path_from_id(fn_node_id); + exported_name(path, &hash[..]) }; debug!("monomorphize_fn mangled to {}", s); diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index dab4056b4af81..3492635a20be4 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -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 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 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 { diff --git a/src/librustdoc/html/format.rs b/src/librustdoc/html/format.rs index 6937dbf255e2e..d12c5d2c6fb6b 100644 --- a/src/librustdoc/html/format.rs +++ b/src/librustdoc/html/format.rs @@ -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()), diff --git a/src/librustdoc/html/render.rs b/src/librustdoc/html/render.rs index 708c8f634f553..cf03482e18b8a 100644 --- a/src/librustdoc/html/render.rs +++ b/src/librustdoc/html/render.rs @@ -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, "[src]", - 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)); } } diff --git a/src/libsyntax/ast.rs b/src/libsyntax/ast.rs index 45e1d00586327..d186918f44aaa 100644 --- a/src/libsyntax/ast.rs +++ b/src/libsyntax/ast.rs @@ -167,13 +167,13 @@ impl fmt::Display for Ident { impl Encodable for Ident { fn encode(&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: &mut D) -> Result { - Ok(str_to_ident(&try!(d.read_str())[..])) + Ok(Ident::with_empty_ctxt(try!(Name::decode(d)))) } }