diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 18179027c25..3cf7548e320 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -103,18 +103,13 @@ pub enum DepNode { // table in the tcx (or elsewhere) maps to one of these // nodes. Often we map multiple tables to the same node if there // is no point in distinguishing them (e.g., both the type and - // predicates for an item wind up in `ItemSignature`). Other - // times, such as `ImplItems` vs `TraitItemDefIds`, tables which - // might be mergable are kept distinct because the sets of def-ids - // to which they apply are disjoint, and hence we might as well - // have distinct labels for easier debugging. + // predicates for an item wind up in `ItemSignature`). ImplOrTraitItems(D), ItemSignature(D), FieldTy(D), SizedConstraint(D), - TraitItemDefIds(D), + ImplOrTraitItemIds(D), InherentImpls(D), - ImplItems(D), // The set of impls for a given trait. Ultimately, it would be // nice to get more fine-grained here (e.g., to include a @@ -162,9 +157,8 @@ impl DepNode { ImplOrTraitItems, ItemSignature, FieldTy, - TraitItemDefIds, + ImplOrTraitItemIds, InherentImpls, - ImplItems, TraitImpls, ReprHints, } @@ -231,9 +225,8 @@ impl DepNode { ItemSignature(ref d) => op(d).map(ItemSignature), FieldTy(ref d) => op(d).map(FieldTy), SizedConstraint(ref d) => op(d).map(SizedConstraint), - TraitItemDefIds(ref d) => op(d).map(TraitItemDefIds), + ImplOrTraitItemIds(ref d) => op(d).map(ImplOrTraitItemIds), InherentImpls(ref d) => op(d).map(InherentImpls), - ImplItems(ref d) => op(d).map(ImplItems), TraitImpls(ref d) => op(d).map(TraitImpls), TraitItems(ref d) => op(d).map(TraitItems), ReprHints(ref d) => op(d).map(ReprHints), diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index b4418ed424e..fddf09c9905 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -92,7 +92,7 @@ pub type DefMap = NodeMap; // within. pub type ExportMap = NodeMap>; -#[derive(Copy, Clone)] +#[derive(Copy, Clone, RustcEncodable, RustcDecodable)] pub struct Export { pub name: ast::Name, // The name of the target. pub def_id: DefId, // The definition of the target. diff --git a/src/librustc/hir/map/mod.rs b/src/librustc/hir/map/mod.rs index b728f1cbca0..b351bd427ac 100644 --- a/src/librustc/hir/map/mod.rs +++ b/src/librustc/hir/map/mod.rs @@ -580,22 +580,24 @@ impl<'ast> Map<'ast> { } } - pub fn expect_struct(&self, id: NodeId) -> &'ast VariantData { + pub fn expect_variant_data(&self, id: NodeId) -> &'ast VariantData { match self.find(id) { Some(NodeItem(i)) => { match i.node { - ItemStruct(ref struct_def, _) => struct_def, - _ => bug!("struct ID bound to non-struct") + ItemStruct(ref struct_def, _) | + ItemUnion(ref struct_def, _) => struct_def, + _ => { + bug!("struct ID bound to non-struct {}", + self.node_to_string(id)); + } } } - Some(NodeVariant(variant)) => { - if variant.node.data.is_struct() { - &variant.node.data - } else { - bug!("struct ID bound to enum variant that isn't struct-like") - } + Some(NodeStructCtor(data)) => data, + Some(NodeVariant(variant)) => &variant.node.data, + _ => { + bug!("expected struct or variant, found {}", + self.node_to_string(id)); } - _ => bug!("expected struct, found {}", self.node_to_string(id)), } } diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 1d6047579f6..52cadd76c64 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -28,14 +28,13 @@ use hir::map as hir_map; use hir::map::definitions::DefKey; use hir::svh::Svh; use middle::lang_items; -use ty::{self, Ty, TyCtxt, VariantKind}; +use ty::{self, Ty, TyCtxt}; use mir::repr::Mir; use mir::mir_map::MirMap; use session::Session; use session::config::PanicStrategy; use session::search_paths::PathKind; -use util::nodemap::{FnvHashMap, NodeSet, DefIdMap}; -use std::rc::Rc; +use util::nodemap::{NodeSet, DefIdMap}; use std::path::PathBuf; use syntax::ast; use syntax::attr; @@ -47,7 +46,6 @@ use rustc_back::target::Target; use hir; use hir::intravisit::Visitor; -pub use self::DefLike::{DlDef, DlField, DlImpl}; pub use self::NativeLibraryKind::{NativeStatic, NativeFramework, NativeUnknown}; // lonely orphan structs and enums looking for a better home @@ -67,27 +65,17 @@ pub struct CrateSource { pub cnum: CrateNum, } -#[derive(Copy, Debug, PartialEq, Clone)] +#[derive(Copy, Debug, PartialEq, Clone, RustcEncodable, RustcDecodable)] pub enum LinkagePreference { RequireDynamic, RequireStatic, } -enum_from_u32! { - #[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)] - pub enum NativeLibraryKind { - NativeStatic, // native static library (.a archive) - NativeFramework, // OSX-specific - NativeUnknown, // default way to specify a dynamic library - } -} - -// Something that a name can resolve to. -#[derive(Copy, Clone, Debug)] -pub enum DefLike { - DlDef(Def), - DlImpl(DefId), - DlField +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, RustcEncodable, RustcDecodable)] +pub enum NativeLibraryKind { + NativeStatic, // native static library (.a archive) + NativeFramework, // OSX-specific + NativeUnknown, // default way to specify a dynamic library } /// The data we save and restore about an inlined item or method. This is not @@ -110,7 +98,7 @@ pub enum InlinedItemRef<'a> { #[derive(Copy, Clone)] pub struct ChildItem { - pub def: DefLike, + pub def: Def, pub name: ast::Name, pub vis: ty::Visibility, } @@ -166,21 +154,15 @@ pub trait CrateStore<'tcx> { fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec; // trait info - fn implementations_of_trait(&self, def_id: DefId) -> Vec; - fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Vec>>; - fn trait_item_def_ids(&self, def: DefId) - -> Vec; + fn implementations_of_trait(&self, filter: Option) -> Vec; // impl info - fn impl_items(&self, impl_def_id: DefId) -> Vec; + fn impl_or_trait_items(&self, def_id: DefId) -> Vec; fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Option>; - fn impl_polarity(&self, def: DefId) -> Option; + fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity; fn custom_coerce_unsized_kind(&self, def: DefId) -> Option; - fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Vec>>; fn impl_parent(&self, impl_def_id: DefId) -> Option; // trait/impl-item info @@ -191,12 +173,10 @@ pub trait CrateStore<'tcx> { // flags fn is_const_fn(&self, did: DefId) -> bool; fn is_defaulted_trait(&self, did: DefId) -> bool; - fn is_impl(&self, did: DefId) -> bool; fn is_default_impl(&self, impl_did: DefId) -> bool; fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool; fn is_foreign_item(&self, did: DefId) -> bool; fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool; - fn is_typedef(&self, did: DefId) -> bool; // crate metadata fn dylib_dependency_formats(&self, cnum: CrateNum) @@ -218,8 +198,6 @@ pub trait CrateStore<'tcx> { fn original_crate_name(&self, cnum: CrateNum) -> InternedString; fn crate_hash(&self, cnum: CrateNum) -> Svh; fn crate_disambiguator(&self, cnum: CrateNum) -> InternedString; - fn crate_struct_field_attrs(&self, cnum: CrateNum) - -> FnvHashMap>; fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option; fn native_libraries(&self, cnum: CrateNum) -> Vec<(NativeLibraryKind, String)>; fn reachable_ids(&self, cnum: CrateNum) -> Vec; @@ -232,12 +210,10 @@ pub trait CrateStore<'tcx> { -> Option; fn def_key(&self, def: DefId) -> hir_map::DefKey; fn relative_def_path(&self, def: DefId) -> Option; - fn variant_kind(&self, def_id: DefId) -> Option; fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option; fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option; fn struct_field_names(&self, def: DefId) -> Vec; fn item_children(&self, did: DefId) -> Vec; - fn crate_top_level_items(&self, cnum: CrateNum) -> Vec; // misc. metadata fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) @@ -344,11 +320,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec { vec![] } // trait info - fn implementations_of_trait(&self, def_id: DefId) -> Vec { vec![] } - fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Vec>> { bug!("provided_trait_methods") } - fn trait_item_def_ids(&self, def: DefId) - -> Vec { bug!("trait_item_def_ids") } + fn implementations_of_trait(&self, filter: Option) -> Vec { vec![] } fn def_index_for_def_key(&self, cnum: CrateNum, def: DefKey) @@ -357,16 +329,14 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { } // impl info - fn impl_items(&self, impl_def_id: DefId) -> Vec - { bug!("impl_items") } + fn impl_or_trait_items(&self, def_id: DefId) -> Vec + { bug!("impl_or_trait_items") } fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Option> { bug!("impl_trait_ref") } - fn impl_polarity(&self, def: DefId) -> Option { bug!("impl_polarity") } + fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { bug!("impl_polarity") } fn custom_coerce_unsized_kind(&self, def: DefId) -> Option { bug!("custom_coerce_unsized_kind") } - fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Vec>> { bug!("associated_consts") } fn impl_parent(&self, def: DefId) -> Option { bug!("impl_parent") } // trait/impl-item info @@ -377,13 +347,11 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { // flags fn is_const_fn(&self, did: DefId) -> bool { bug!("is_const_fn") } fn is_defaulted_trait(&self, did: DefId) -> bool { bug!("is_defaulted_trait") } - fn is_impl(&self, did: DefId) -> bool { bug!("is_impl") } fn is_default_impl(&self, impl_did: DefId) -> bool { bug!("is_default_impl") } fn is_extern_item<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> bool { bug!("is_extern_item") } fn is_foreign_item(&self, did: DefId) -> bool { bug!("is_foreign_item") } fn is_statically_included_foreign_item(&self, id: ast::NodeId) -> bool { false } - fn is_typedef(&self, did: DefId) -> bool { bug!("is_typedef") } // crate metadata fn dylib_dependency_formats(&self, cnum: CrateNum) @@ -411,9 +379,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn crate_hash(&self, cnum: CrateNum) -> Svh { bug!("crate_hash") } fn crate_disambiguator(&self, cnum: CrateNum) -> InternedString { bug!("crate_disambiguator") } - fn crate_struct_field_attrs(&self, cnum: CrateNum) - -> FnvHashMap> - { bug!("crate_struct_field_attrs") } fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option { bug!("plugin_registrar_fn") } fn native_libraries(&self, cnum: CrateNum) -> Vec<(NativeLibraryKind, String)> @@ -426,15 +391,12 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn relative_def_path(&self, def: DefId) -> Option { bug!("relative_def_path") } - fn variant_kind(&self, def_id: DefId) -> Option { bug!("variant_kind") } fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option { bug!("struct_ctor_def_id") } fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option { bug!("tuple_struct_definition_if_ctor") } fn struct_field_names(&self, def: DefId) -> Vec { bug!("struct_field_names") } fn item_children(&self, did: DefId) -> Vec { bug!("item_children") } - fn crate_top_level_items(&self, cnum: CrateNum) -> Vec - { bug!("crate_top_level_items") } // misc. metadata fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 9db6ac1dcef..2c952e9f863 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -470,7 +470,7 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { // This is done to handle the case where, for example, the static // method of a private type is used, but the type itself is never // called directly. - let impl_items = self.tcx.impl_items.borrow(); + let impl_items = self.tcx.impl_or_trait_item_ids.borrow(); if let Some(impl_list) = self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) { for impl_did in impl_list.iter() { diff --git a/src/librustc/middle/lang_items.rs b/src/librustc/middle/lang_items.rs index d1769d5cbc5..078cce9c49f 100644 --- a/src/librustc/middle/lang_items.rs +++ b/src/librustc/middle/lang_items.rs @@ -43,7 +43,7 @@ macro_rules! language_item_table { enum_from_u32! { - #[derive(Copy, Clone, PartialEq, Eq, Hash)] + #[derive(Copy, Clone, PartialEq, Eq, Hash, RustcEncodable, RustcDecodable)] pub enum LangItem { $($variant,)* } diff --git a/src/librustc/session/config.rs b/src/librustc/session/config.rs index 2009e18f6ee..8dd5d4d45f7 100644 --- a/src/librustc/session/config.rs +++ b/src/librustc/session/config.rs @@ -493,7 +493,7 @@ impl Passes { } } -#[derive(Clone, PartialEq, Hash)] +#[derive(Clone, PartialEq, Hash, RustcEncodable, RustcDecodable)] pub enum PanicStrategy { Unwind, Abort, diff --git a/src/librustc/traits/select.rs b/src/librustc/traits/select.rs index 94dba7d12a8..9d7131dc96c 100644 --- a/src/librustc/traits/select.rs +++ b/src/librustc/traits/select.rs @@ -814,7 +814,7 @@ impl<'cx, 'gcx, 'tcx> SelectionContext<'cx, 'gcx, 'tcx> { fn filter_negative_impls(&self, candidate: SelectionCandidate<'tcx>) -> SelectionResult<'tcx, SelectionCandidate<'tcx>> { if let ImplCandidate(def_id) = candidate { - if self.tcx().trait_impl_polarity(def_id) == Some(hir::ImplPolarity::Negative) { + if self.tcx().trait_impl_polarity(def_id) == hir::ImplPolarity::Negative { return Err(Unimplemented) } } diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 13193e1b2d7..4339b1a254f 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::cell; use std::rc::Rc; use super::{OverlapError, specializes}; @@ -287,21 +286,10 @@ impl<'a, 'gcx, 'tcx> Node { /// Iterate over the items defined directly by the given (impl or trait) node. pub fn items(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> NodeItems<'a, 'gcx> { - match *self { - Node::Impl(impl_def_id) => { - NodeItems::Impl { - tcx: tcx.global_tcx(), - items: cell::Ref::map(tcx.impl_items.borrow(), - |impl_items| &impl_items[&impl_def_id]), - idx: 0, - } - } - Node::Trait(trait_def_id) => { - NodeItems::Trait { - items: tcx.trait_items(trait_def_id).clone(), - idx: 0, - } - } + NodeItems { + tcx: tcx.global_tcx(), + items: tcx.impl_or_trait_items(self.def_id()), + idx: 0, } } @@ -314,42 +302,23 @@ impl<'a, 'gcx, 'tcx> Node { } /// An iterator over the items defined within a trait or impl. -pub enum NodeItems<'a, 'tcx: 'a> { - Impl { - tcx: TyCtxt<'a, 'tcx, 'tcx>, - items: cell::Ref<'a, Vec>, - idx: usize, - }, - Trait { - items: Rc>>, - idx: usize, - }, +pub struct NodeItems<'a, 'tcx: 'a> { + tcx: TyCtxt<'a, 'tcx, 'tcx>, + items: Rc>, + idx: usize } impl<'a, 'tcx> Iterator for NodeItems<'a, 'tcx> { type Item = ImplOrTraitItem<'tcx>; fn next(&mut self) -> Option> { - match *self { - NodeItems::Impl { tcx, ref items, ref mut idx } => { - let items_table = tcx.impl_or_trait_items.borrow(); - if *idx < items.len() { - let item_def_id = items[*idx].def_id(); - let item = items_table[&item_def_id].clone(); - *idx += 1; - Some(item) - } else { - None - } - } - NodeItems::Trait { ref items, ref mut idx } => { - if *idx < items.len() { - let item = items[*idx].clone(); - *idx += 1; - Some(item) - } else { - None - } - } + if self.idx < self.items.len() { + let item_def_id = self.items[self.idx].def_id(); + let items_table = self.tcx.impl_or_trait_items.borrow(); + let item = items_table[&item_def_id].clone(); + self.idx += 1; + Some(item) + } else { + None } } } diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 338ea6b0dd6..0d6beb34c69 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -330,8 +330,8 @@ pub struct GlobalCtxt<'tcx> { /// Maps from a trait item to the trait item "descriptor" pub impl_or_trait_items: RefCell>>, - /// Maps from a trait def-id to a list of the def-ids of its trait items - pub trait_item_def_ids: RefCell>>, + /// Maps from an impl/trait def-id to a list of the def-ids of its items + pub impl_or_trait_item_ids: RefCell>>, /// A cache for the trait_items() routine; note that the routine /// itself pushes the `TraitItems` dependency node. @@ -392,12 +392,6 @@ pub struct GlobalCtxt<'tcx> { /// Methods in these implementations don't need to be exported. pub inherent_impls: RefCell>>, - /// Maps a DefId of an impl to a list of its items. - /// Note that this contains all of the impls that we know about, - /// including ones in other crates. It's not clear that this is the best - /// way to do it. - pub impl_items: RefCell>>, - /// Set of used unsafe nodes (functions or blocks). Unsafe nodes not /// present in this set can be warned about. pub used_unsafe: RefCell, @@ -734,13 +728,12 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { rcache: RefCell::new(FnvHashMap()), tc_cache: RefCell::new(FnvHashMap()), impl_or_trait_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())), - trait_item_def_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())), + impl_or_trait_item_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())), trait_items_cache: RefCell::new(DepTrackingMap::new(dep_graph.clone())), ty_param_defs: RefCell::new(NodeMap()), normalized_cache: RefCell::new(FnvHashMap()), lang_items: lang_items, inherent_impls: RefCell::new(DepTrackingMap::new(dep_graph.clone())), - impl_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())), used_unsafe: RefCell::new(NodeSet()), used_mut_nodes: RefCell::new(NodeSet()), used_trait_imports: RefCell::new(NodeSet()), @@ -1401,7 +1394,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { pub fn trait_items(self, trait_did: DefId) -> Rc>> { self.trait_items_cache.memoize(trait_did, || { - let def_ids = self.trait_item_def_ids(trait_did); + let def_ids = self.impl_or_trait_items(trait_did); Rc::new(def_ids.iter() .map(|d| self.impl_or_trait_item(d.def_id())) .collect()) diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 5772d16c6d4..5e029cf98dc 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -34,13 +34,13 @@ dep_map_ty! { Tcache: ItemSignature(DefId) -> Ty<'tcx> } dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics<'tcx> } dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> } dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> } -dep_map_ty! { TraitItemDefIds: TraitItemDefIds(DefId) -> Rc> } +dep_map_ty! { ImplOrTraitItemIds: ImplOrTraitItemIds(DefId) + -> Rc> } dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option> } dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef<'tcx> } dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> } dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc> } dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec } -dep_map_ty! { ImplItems: ImplItems(DefId) -> Vec } dep_map_ty! { TraitItems: TraitItems(DefId) -> Rc>> } dep_map_ty! { ReprHints: ReprHints(DefId) -> Rc> } dep_map_ty! { InlinedClosures: Hir(DefId) -> ast::NodeId } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 59475b42226..3eb9f8593e3 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -50,7 +50,6 @@ use syntax_pos::{DUMMY_SP, Span}; use rustc_const_math::ConstInt; use hir; -use hir::{ItemImpl, ItemTrait, PatKind}; use hir::intravisit::Visitor; pub use self::sty::{Binder, DebruijnIndex}; @@ -251,7 +250,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> { } } -#[derive(Clone, Copy, Debug)] +#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable)] pub enum ImplOrTraitItemId { ConstTraitItemId(DefId), MethodTraitItemId(DefId), @@ -268,7 +267,7 @@ impl ImplOrTraitItemId { } } -#[derive(Clone, Debug, PartialEq, Eq, Copy)] +#[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)] pub enum Visibility { /// Visible everywhere (including in other crates). Public, @@ -346,34 +345,12 @@ pub struct Method<'tcx> { pub explicit_self: ExplicitSelfCategory<'tcx>, pub vis: Visibility, pub defaultness: hir::Defaultness, + pub has_body: bool, pub def_id: DefId, pub container: ImplOrTraitItemContainer, } impl<'tcx> Method<'tcx> { - pub fn new(name: Name, - generics: &'tcx ty::Generics<'tcx>, - predicates: GenericPredicates<'tcx>, - fty: &'tcx BareFnTy<'tcx>, - explicit_self: ExplicitSelfCategory<'tcx>, - vis: Visibility, - defaultness: hir::Defaultness, - def_id: DefId, - container: ImplOrTraitItemContainer) - -> Method<'tcx> { - Method { - name: name, - generics: generics, - predicates: predicates, - fty: fty, - explicit_self: explicit_self, - vis: vis, - defaultness: defaultness, - def_id: def_id, - container: container, - } - } - pub fn container_id(&self) -> DefId { match self.container { TraitContainer(id) => id, @@ -2236,7 +2213,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { match self.map.find(id) { Some(ast_map::NodeLocal(pat)) => { match pat.node { - PatKind::Binding(_, ref path1, _) => path1.node.as_str(), + hir::PatKind::Binding(_, ref path1, _) => path1.node.as_str(), _ => { bug!("Variable id {} maps to {:?}, not local", id, pat); }, @@ -2299,84 +2276,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn provided_trait_methods(self, id: DefId) -> Vec>> { - if let Some(id) = self.map.as_local_node_id(id) { - if let ItemTrait(.., ref ms) = self.map.expect_item(id).node { - ms.iter().filter_map(|ti| { - if let hir::MethodTraitItem(_, Some(_)) = ti.node { - match self.impl_or_trait_item(self.map.local_def_id(ti.id)) { - MethodTraitItem(m) => Some(m), - _ => { - bug!("provided_trait_methods(): \ - non-method item found from \ - looking up provided method?!") - } - } - } else { - None - } - }).collect() - } else { - bug!("provided_trait_methods: `{:?}` is not a trait", id) + self.impl_or_trait_items(id).iter().filter_map(|id| { + match self.impl_or_trait_item(id.def_id()) { + MethodTraitItem(ref m) if m.has_body => Some(m.clone()), + _ => None } - } else { - self.sess.cstore.provided_trait_methods(self.global_tcx(), id) - } + }).collect() } - pub fn associated_consts(self, id: DefId) -> Vec>> { + pub fn trait_impl_polarity(self, id: DefId) -> hir::ImplPolarity { if let Some(id) = self.map.as_local_node_id(id) { match self.map.expect_item(id).node { - ItemTrait(.., ref tis) => { - tis.iter().filter_map(|ti| { - if let hir::ConstTraitItem(..) = ti.node { - match self.impl_or_trait_item(self.map.local_def_id(ti.id)) { - ConstTraitItem(ac) => Some(ac), - _ => { - bug!("associated_consts(): \ - non-const item found from \ - looking up a constant?!") - } - } - } else { - None - } - }).collect() - } - ItemImpl(.., ref iis) => { - iis.iter().filter_map(|ii| { - if let hir::ImplItemKind::Const(..) = ii.node { - match self.impl_or_trait_item(self.map.local_def_id(ii.id)) { - ConstTraitItem(ac) => Some(ac), - _ => { - bug!("associated_consts(): \ - non-const item found from \ - looking up a constant?!") - } - } - } else { - None - } - }).collect() - } - _ => { - bug!("associated_consts: `{:?}` is not a trait or impl", id) - } - } - } else { - self.sess.cstore.associated_consts(self.global_tcx(), id) - } - } - - pub fn trait_impl_polarity(self, id: DefId) -> Option { - if let Some(id) = self.map.as_local_node_id(id) { - match self.map.find(id) { - Some(ast_map::NodeItem(item)) => { - match item.node { - hir::ItemImpl(_, polarity, ..) => Some(polarity), - _ => None - } - } - _ => None + hir::ItemImpl(_, polarity, ..) => polarity, + ref item => bug!("trait_impl_polarity: {:?} not an impl", item) } } else { self.sess.cstore.impl_polarity(id) @@ -2409,10 +2321,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .expect("missing ImplOrTraitItem in metadata")) } - pub fn trait_item_def_ids(self, id: DefId) -> Rc> { + pub fn impl_or_trait_items(self, id: DefId) -> Rc> { lookup_locally_or_in_crate_store( - "trait_item_def_ids", id, &self.trait_item_def_ids, - || Rc::new(self.sess.cstore.trait_item_def_ids(id))) + "impl_or_trait_items", id, &self.impl_or_trait_item_ids, + || Rc::new(self.sess.cstore.impl_or_trait_items(id))) } /// Returns the trait-ref corresponding to a given impl, or None if it is @@ -2423,20 +2335,6 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { || self.sess.cstore.impl_trait_ref(self.global_tcx(), id)) } - /// Returns whether this DefId refers to an impl - pub fn is_impl(self, id: DefId) -> bool { - if let Some(id) = self.map.as_local_node_id(id) { - if let Some(ast_map::NodeItem( - &hir::Item { node: hir::ItemImpl(..), .. })) = self.map.find(id) { - true - } else { - false - } - } else { - self.sess.cstore.is_impl(id) - } - } - /// Returns a path resolution for node id if it exists, panics otherwise. pub fn expect_resolution(self, id: NodeId) -> PathResolution { *self.def_map.borrow().get(&id).expect("no def-map entry for node id") @@ -2699,10 +2597,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { debug!("populate_implementations_for_primitive_if_necessary: searching for {:?}", primitive_def_id); - let impl_items = self.sess.cstore.impl_items(primitive_def_id); + let impl_items = self.sess.cstore.impl_or_trait_items(primitive_def_id); // Store the implementation info. - self.impl_items.borrow_mut().insert(primitive_def_id, impl_items); + self.impl_or_trait_item_ids.borrow_mut().insert(primitive_def_id, Rc::new(impl_items)); self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id); } @@ -2728,8 +2626,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let inherent_impls = self.sess.cstore.inherent_implementations_for_type(type_id); for &impl_def_id in &inherent_impls { // Store the implementation info. - let impl_items = self.sess.cstore.impl_items(impl_def_id); - self.impl_items.borrow_mut().insert(impl_def_id, impl_items); + let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id); + self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items)); } self.inherent_impls.borrow_mut().insert(type_id, inherent_impls); @@ -2758,8 +2656,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.record_trait_has_default_impl(trait_id); } - for impl_def_id in self.sess.cstore.implementations_of_trait(trait_id) { - let impl_items = self.sess.cstore.impl_items(impl_def_id); + for impl_def_id in self.sess.cstore.implementations_of_trait(Some(trait_id)) { + let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id); let trait_ref = self.impl_trait_ref(impl_def_id).unwrap(); // Record the trait->implementation mapping. @@ -2779,7 +2677,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } // Store the implementation info. - self.impl_items.borrow_mut().insert(impl_def_id, impl_items); + self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items)); } def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID); @@ -3012,7 +2910,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } /// The category of explicit self. -#[derive(Clone, Copy, Eq, PartialEq, Debug)] +#[derive(Clone, Copy, Eq, PartialEq, Debug, RustcEncodable, RustcDecodable)] pub enum ExplicitSelfCategory<'tcx> { Static, ByValue, diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index ede13aa4dc8..fe3c498d184 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -1080,9 +1080,17 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // when constructing the inference context above. match selection { traits::VtableImpl(ref impl_data) => { - match tcx.associated_consts(impl_data.impl_def_id) - .iter().find(|ic| ic.name == ti.name) { - Some(ic) => lookup_const_by_id(tcx, ic.def_id, None), + let ac = tcx.impl_or_trait_items(impl_data.impl_def_id) + .iter().filter_map(|id| { + match *id { + ty::ConstTraitItemId(def_id) => { + Some(tcx.impl_or_trait_item(def_id)) + } + _ => None + } + }).find(|ic| ic.name() == ti.name); + match ac { + Some(ic) => lookup_const_by_id(tcx, ic.def_id(), None), None => match ti.node { hir::ConstTraitItem(ref ty, Some(ref expr)) => { Some((&*expr, tcx.ast_ty_to_prim_ty(ty))) diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs index 123ed11a7a5..94581a3fc89 100644 --- a/src/librustc_metadata/common.rs +++ b/src/librustc_metadata/common.rs @@ -10,13 +10,38 @@ #![allow(non_camel_case_types, non_upper_case_globals)] +use rustc::ty; + +#[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)] +pub enum Family { + ImmStatic, + MutStatic, + Fn, + Method, + AssociatedType, + Type, + Mod, + ForeignMod, + Enum, + Variant(ty::VariantKind), + Impl, + DefaultImpl, + Trait, + Struct(ty::VariantKind), + Union, + PublicField, + InheritedField, + Const, + AssociatedConst, +} + // GAP 0x00...0x19 pub const tag_items: usize = 0x100; // top-level only pub const tag_paths_data_name: usize = 0x20; -pub const tag_def_id: usize = 0x21; +pub const tag_def_index: usize = 0x21; pub const tag_items_data: usize = 0x22; @@ -26,9 +51,7 @@ pub const tag_items_data_item_family: usize = 0x24; pub const tag_items_data_item_type: usize = 0x25; -// GAP 0x26 - -pub const tag_items_data_item_variant: usize = 0x27; +// GAP 0x26, 0x27 pub const tag_items_data_parent_item: usize = 0x28; @@ -47,19 +70,11 @@ pub const tag_attributes: usize = 0x101; // top-level only // The list of crates that this crate depends on pub const tag_crate_deps: usize = 0x102; // top-level only - -// A single crate dependency -pub const tag_crate_dep: usize = 0x35; - pub const tag_crate_hash: usize = 0x103; // top-level only pub const tag_crate_crate_name: usize = 0x104; // top-level only pub const tag_crate_disambiguator: usize = 0x113; // top-level only -pub const tag_crate_dep_crate_name: usize = 0x36; -pub const tag_crate_dep_hash: usize = 0x37; -pub const tag_crate_dep_explicitly_linked: usize = 0x38; // top-level only - -pub const tag_item_trait_item: usize = 0x3a; +// GAP 0x35, 0x36, 0x37, 0x38, 0x39, 0x3a pub const tag_item_trait_ref: usize = 0x3b; @@ -68,26 +83,13 @@ pub const tag_disr_val: usize = 0x3c; // GAP 0x3d, 0x3e, 0x3f, 0x40 -pub const tag_item_field: usize = 0x41; +pub const tag_item_fields: usize = 0x41; // GAP 0x42 pub const tag_item_variances: usize = 0x43; -/* - trait items contain tag_item_trait_item elements, - impl items contain tag_item_impl_item elements, and classes - have both. That's because some code treats classes like traits, - and other code treats them like impls. Because classes can contain - both, tag_item_trait_item and tag_item_impl_item have to be two - different tags. - */ -pub const tag_item_impl_item: usize = 0x44; +// GAP 0x44 pub const tag_item_trait_method_explicit_self: usize = 0x45; - -// Reexports are found within module tags. Each reexport contains def_ids -// and names. -pub const tag_items_data_item_reexport: usize = 0x46; -pub const tag_items_data_item_reexport_def_id: usize = 0x47; -pub const tag_items_data_item_reexport_name: usize = 0x48; +// GAP 0x46, 0x47, 0x48 // used to encode crate_ctxt side tables pub const tag_ast: usize = 0x50; @@ -98,58 +100,58 @@ pub const tag_mir: usize = 0x52; // GAP 0x53...0x6a -pub const tag_item_trait_item_sort: usize = 0x70; +pub const tag_item_trait_item_has_body: usize = 0x70; pub const tag_crate_triple: usize = 0x105; // top-level only pub const tag_dylib_dependency_formats: usize = 0x106; // top-level only -// Language items are a top-level directory (for speed). Hierarchy: -// -// tag_lang_items -// - tag_lang_items_item -// - tag_lang_items_item_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_index: usize = 0x75; -pub const tag_lang_items_missing: usize = 0x76; -pub const tag_item_unnamed_field: usize = 0x77; +// GAP 0x73, 0x74, 0x75 + +pub const tag_lang_items_missing: usize = 0x76; // top-level only + +// GAP 0x77 + pub const tag_items_data_item_visibility: usize = 0x78; -pub const tag_items_data_item_inherent_impl: usize = 0x79; +pub const tag_items_data_item_inherent_impls: usize = 0x79; + // GAP 0x7a -pub const tag_mod_child: usize = 0x7b; + +// GAP 0x7c +pub const tag_mod_children: usize = 0x7b; + +// GAP 0x108 // top-level only + // GAP 0x7c // GAP 0x108 pub const tag_impls: usize = 0x109; // top-level only -pub const tag_impls_trait: usize = 0x7d; -pub const tag_impls_trait_impl: usize = 0x7e; -// GAP 0x7f, 0x80, 0x81 +// GAP 0x7d, 0x7e, 0x7f, 0x80, 0x81 pub const tag_native_libraries: usize = 0x10a; // top-level only -pub const tag_native_libraries_lib: usize = 0x82; -pub const tag_native_libraries_name: usize = 0x83; -pub const tag_native_libraries_kind: usize = 0x84; + +// GAP 0x82, 0x83, 0x84 pub const tag_plugin_registrar_fn: usize = 0x10b; // top-level only pub const tag_method_argument_names: usize = 0x85; -pub const tag_method_argument_name: usize = 0x86; + +// GAP 0x86 pub const tag_reachable_ids: usize = 0x10c; // top-level only -pub const tag_reachable_id: usize = 0x87; + +// GAP 0x87 pub const tag_items_data_item_stability: usize = 0x88; pub const tag_items_data_item_repr: usize = 0x89; -pub const tag_struct_fields: usize = 0x10d; // top-level only -pub const tag_struct_field: usize = 0x8a; +// GAP 0x10d // top-level only + +// GAP 0x8a pub const tag_items_data_item_struct_ctor: usize = 0x8b; pub const tag_attribute_is_sugared_doc: usize = 0x8c; @@ -160,10 +162,7 @@ pub const tag_item_generics: usize = 0x8f; // GAP 0x90, 0x91, 0x92, 0x93, 0x94 pub const tag_item_predicates: usize = 0x95; -// GAP 0x96 - -pub const tag_predicate: usize = 0x97; -// GAP 0x98, 0x99 +// GAP 0x96, 0x97, 0x98, 0x99 pub const tag_unsafety: usize = 0x9a; @@ -173,15 +172,14 @@ pub const tag_associated_type_name: usize = 0x9c; pub const tag_polarity: usize = 0x9d; pub const tag_macro_defs: usize = 0x10e; // top-level only -pub const tag_macro_def: usize = 0x9e; -pub const tag_macro_def_body: usize = 0x9f; -pub const tag_macro_def_span_lo: usize = 0xa8; -pub const tag_macro_def_span_hi: usize = 0xa9; + +// GAP 0x9e, 0x9f pub const tag_paren_sugar: usize = 0xa0; pub const tag_codemap: usize = 0xa1; -pub const tag_codemap_filemap: usize = 0xa2; + +// GAP 0xa2 pub const tag_item_super_predicates: usize = 0xa3; diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 2774ffdf6c7..7b6ed4e6b76 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -264,7 +264,7 @@ impl<'a> CrateReader<'a> { // Check for (potential) conflicts with the local crate if self.local_crate_name == crate_name && - self.sess.local_crate_disambiguator() == disambiguator { + self.sess.local_crate_disambiguator() == &disambiguator[..] { span_fatal!(self.sess, span, E0519, "the current crate is indistinguishable from one of its \ dependencies: it has the same crate-name `{}` and was \ @@ -320,7 +320,6 @@ impl<'a> CrateReader<'a> { let loader::Library { dylib, rlib, metadata } = lib; let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), cnum, span); - let staged_api = self.is_staged_api(metadata.as_slice()); let cmeta = Rc::new(cstore::CrateMetadata { name: name.to_string(), @@ -332,7 +331,6 @@ impl<'a> CrateReader<'a> { cnum_map: RefCell::new(cnum_map), cnum: cnum, codemap_import_info: RefCell::new(vec![]), - staged_api: staged_api, explicitly_linked: Cell::new(explicitly_linked), }); @@ -352,16 +350,6 @@ impl<'a> CrateReader<'a> { (cnum, cmeta, source) } - fn is_staged_api(&self, data: &[u8]) -> bool { - let attrs = decoder::get_crate_attributes(data); - for attr in &attrs { - if attr.name() == "stable" || attr.name() == "unstable" { - return true - } - } - false - } - fn resolve_crate(&mut self, root: &Option, ident: &str, diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index b291c4927aa..38b18fa63e3 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -14,11 +14,11 @@ use decoder; use encoder; use loader; -use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate, DefLike}; +use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate}; use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference}; use rustc::hir::def; use middle::lang_items; -use rustc::ty::{self, Ty, TyCtxt, VariantKind}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; use rustc::dep_graph::DepNode; @@ -26,10 +26,9 @@ use rustc::hir::map as hir_map; use rustc::hir::map::DefKey; use rustc::mir::repr::Mir; use rustc::mir::mir_map::MirMap; -use rustc::util::nodemap::{FnvHashMap, NodeSet, DefIdMap}; +use rustc::util::nodemap::{NodeSet, DefIdMap}; use rustc::session::config::PanicStrategy; -use std::rc::Rc; use std::path::PathBuf; use syntax::ast; use syntax::attr; @@ -166,42 +165,27 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { result } - fn implementations_of_trait(&self, def_id: DefId) -> Vec + fn implementations_of_trait(&self, filter: Option) -> Vec { - self.dep_graph.read(DepNode::MetaData(def_id)); + if let Some(def_id) = filter { + self.dep_graph.read(DepNode::MetaData(def_id)); + } let mut result = vec![]; self.iter_crate_data(|_, cdata| { - decoder::each_implementation_for_trait(cdata, def_id, &mut |iid| { + decoder::each_implementation_for_trait(cdata, filter, &mut |iid| { result.push(iid) }) }); result } - fn provided_trait_methods<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Vec>> - { - self.dep_graph.read(DepNode::MetaData(def)); - let cdata = self.get_crate_data(def.krate); - decoder::get_provided_trait_methods(&cdata, def.index, tcx) + fn impl_or_trait_items(&self, def_id: DefId) -> Vec { + self.dep_graph.read(DepNode::MetaData(def_id)); + let cdata = self.get_crate_data(def_id.krate); + decoder::get_impl_or_trait_items(&cdata, def_id.index) } - fn trait_item_def_ids(&self, def: DefId) - -> Vec - { - self.dep_graph.read(DepNode::MetaData(def)); - let cdata = self.get_crate_data(def.krate); - decoder::get_trait_item_def_ids(&cdata, def.index) - } - - fn impl_items(&self, impl_def_id: DefId) -> Vec - { - self.dep_graph.read(DepNode::MetaData(impl_def_id)); - let cdata = self.get_crate_data(impl_def_id.krate); - decoder::get_impl_items(&cdata, impl_def_id.index) - } - - fn impl_polarity(&self, def: DefId) -> Option + fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity { self.dep_graph.read(DepNode::MetaData(def)); let cdata = self.get_crate_data(def.krate); @@ -224,14 +208,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_custom_coerce_unsized_kind(&cdata, def.index) } - // FIXME: killme - fn associated_consts<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) - -> Vec>> { - self.dep_graph.read(DepNode::MetaData(def)); - let cdata = self.get_crate_data(def.krate); - decoder::get_associated_consts(&cdata, def.index, tcx) - } - fn impl_parent(&self, impl_def: DefId) -> Option { self.dep_graph.read(DepNode::MetaData(impl_def)); let cdata = self.get_crate_data(impl_def.krate); @@ -266,13 +242,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::is_defaulted_trait(&cdata, trait_def_id.index) } - fn is_impl(&self, did: DefId) -> bool - { - self.dep_graph.read(DepNode::MetaData(did)); - let cdata = self.get_crate_data(did.krate); - decoder::is_impl(&cdata, did.index) - } - fn is_default_impl(&self, impl_did: DefId) -> bool { self.dep_graph.read(DepNode::MetaData(impl_did)); let cdata = self.get_crate_data(impl_did.krate); @@ -295,12 +264,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.do_is_statically_included_foreign_item(id) } - fn is_typedef(&self, did: DefId) -> bool { - self.dep_graph.read(DepNode::MetaData(did)); - let cdata = self.get_crate_data(did.krate); - decoder::is_typedef(&cdata, did.index) - } - fn dylib_dependency_formats(&self, cnum: CrateNum) -> Vec<(CrateNum, LinkagePreference)> { @@ -310,12 +273,8 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn lang_items(&self, cnum: CrateNum) -> Vec<(DefIndex, usize)> { - let mut result = vec![]; let crate_data = self.get_crate_data(cnum); - decoder::each_lang_item(&crate_data, |did, lid| { - result.push((did, lid)); true - }); - result + decoder::get_lang_items(&crate_data) } fn missing_lang_items(&self, cnum: CrateNum) @@ -327,7 +286,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn is_staged_api(&self, cnum: CrateNum) -> bool { - self.get_crate_data(cnum).staged_api + self.get_crate_data(cnum).is_staged_api() } fn is_explicitly_linked(&self, cnum: CrateNum) -> bool @@ -355,7 +314,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn crate_attrs(&self, cnum: CrateNum) -> Vec { - decoder::get_crate_attributes(self.get_crate_data(cnum).data()) + decoder::get_item_attrs(&self.get_crate_data(cnum), CRATE_DEF_INDEX) } fn crate_name(&self, cnum: CrateNum) -> token::InternedString @@ -382,13 +341,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn crate_disambiguator(&self, cnum: CrateNum) -> token::InternedString { let cdata = self.get_crate_data(cnum); - token::intern_and_get_ident(decoder::get_crate_disambiguator(cdata.data())) - } - - fn crate_struct_field_attrs(&self, cnum: CrateNum) - -> FnvHashMap> - { - decoder::get_struct_field_attrs(&self.get_crate_data(cnum)) + token::intern_and_get_ident(&decoder::get_crate_disambiguator(cdata.data())) } fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option @@ -447,12 +400,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::def_path(&cdata, def.index) } - fn variant_kind(&self, def_id: DefId) -> Option { - self.dep_graph.read(DepNode::MetaData(def_id)); - let cdata = self.get_crate_data(def_id.krate); - decoder::get_variant_kind(&cdata, def_id.index) - } - fn struct_ctor_def_id(&self, struct_def_id: DefId) -> Option { self.dep_graph.read(DepNode::MetaData(struct_def_id)); @@ -486,17 +433,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { result } - fn crate_top_level_items(&self, cnum: CrateNum) -> Vec - { - let mut result = vec![]; - let crate_data = self.get_crate_data(cnum); - let get_crate_data = |cnum| self.get_crate_data(cnum); - decoder::each_top_level_item_of_crate(&crate_data, get_crate_data, |def, name, vis| { - result.push(ChildItem { def: def, name: name, vis: vis }); - }); - result - } - fn maybe_get_item_ast<'a>(&'tcx self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) @@ -726,9 +662,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { let mut bfs_queue = &mut VecDeque::new(); let mut add_child = |bfs_queue: &mut VecDeque<_>, child: ChildItem, parent: DefId| { - let child = match child.def { - DefLike::DlDef(def) if child.vis == ty::Visibility::Public => def.def_id(), - _ => return, + let child = if child.vis == ty::Visibility::Public { + child.def.def_id() + } else { + return; }; match visible_parent_map.entry(child) { @@ -746,10 +683,10 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { } }; - let croot = DefId { krate: cnum, index: CRATE_DEF_INDEX }; - for child in self.crate_top_level_items(cnum) { - add_child(bfs_queue, child, croot); - } + bfs_queue.push_back(DefId { + krate: cnum, + index: CRATE_DEF_INDEX + }); while let Some(def) = bfs_queue.pop_front() { for child in self.item_children(def) { add_child(bfs_queue, child, def); @@ -760,4 +697,3 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { visible_parent_map } } - diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 388620a2daf..7aa4677353b 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -22,7 +22,7 @@ use index; use loader; use rustc::dep_graph::DepGraph; -use rustc::hir::def_id::{CrateNum, DefIndex, DefId}; +use rustc::hir::def_id::{CRATE_DEF_INDEX, CrateNum, DefIndex, DefId}; use rustc::hir::map::DefKey; use rustc::hir::svh::Svh; use rustc::middle::cstore::ExternCrate; @@ -77,7 +77,6 @@ pub struct CrateMetadata { pub cnum_map: RefCell, pub cnum: CrateNum, pub codemap_import_info: RefCell>, - pub staged_api: bool, pub index: index::Index, pub xref_index: index::DenseIndex, @@ -300,9 +299,9 @@ impl CStore { impl CrateMetadata { pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() } - pub fn name(&self) -> &str { decoder::get_crate_name(self.data()) } + pub fn name(&self) -> String { decoder::get_crate_name(self.data()) } pub fn hash(&self) -> Svh { decoder::get_crate_hash(self.data()) } - pub fn disambiguator(&self) -> &str { + pub fn disambiguator(&self) -> String { decoder::get_crate_disambiguator(self.data()) } pub fn imported_filemaps<'a>(&'a self, codemap: &codemap::CodeMap) @@ -320,23 +319,30 @@ impl CrateMetadata { } } + pub fn is_staged_api(&self) -> bool { + let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX); + attrs.iter().any(|attr| { + attr.name() == "stable" || attr.name() == "unstable" + }) + } + pub fn is_allocator(&self) -> bool { - let attrs = decoder::get_crate_attributes(self.data()); + let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX); attr::contains_name(&attrs, "allocator") } pub fn needs_allocator(&self) -> bool { - let attrs = decoder::get_crate_attributes(self.data()); + let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX); attr::contains_name(&attrs, "needs_allocator") } pub fn is_panic_runtime(&self) -> bool { - let attrs = decoder::get_crate_attributes(self.data()); + let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX); attr::contains_name(&attrs, "panic_runtime") } pub fn needs_panic_runtime(&self) -> bool { - let attrs = decoder::get_crate_attributes(self.data()); + let attrs = decoder::get_item_attrs(self, CRATE_DEF_INDEX); attr::contains_name(&attrs, "needs_panic_runtime") } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 0118cacad18..507e6414181 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -12,13 +12,11 @@ #![allow(non_camel_case_types)] -use self::Family::*; - use astencode::decode_inlined_item; use cstore::{self, CrateMetadata}; use common::*; +use common::Family::*; use def_key; -use encoder::def_to_u64; use index; use rustc::hir::def_id::CRATE_DEF_INDEX; @@ -31,12 +29,11 @@ use rustc::hir::intravisit::IdRange; use rustc::session::config::PanicStrategy; use middle::cstore::{InlinedItem, LinkagePreference}; -use middle::cstore::{DefLike, DlDef, DlField, DlImpl}; -use rustc::hir::def::Def; +use rustc::hir::def::{self, Def}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; use middle::lang_items; use rustc::ty::{ImplContainer, TraitContainer}; -use rustc::ty::{self, AdtKind, Ty, TyCtxt, TypeFoldable, VariantKind}; +use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; use rustc::ty::subst::Substs; use rustc_const_math::ConstInt; @@ -52,12 +49,9 @@ use std::u32; use rbml::reader; use rbml; use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; -use rustc_serialize as serialize; use syntax::attr; -use syntax::parse::token; use syntax::ast::{self, NodeId}; -use syntax::print::pprust; -use syntax_pos::{self, Span, BytePos, NO_EXPANSION}; +use syntax_pos::{self, Span, BytePos}; pub struct DecodeContext<'a, 'tcx: 'a> { pub opaque: opaque::Decoder<'a>, @@ -94,6 +88,25 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { pub fn cdata(&self) -> &'a cstore::CrateMetadata { self.cdata.expect("missing CrateMetadata in DecodeContext") } + + pub fn decode(&mut self) -> T { + T::decode(self).unwrap() + } + + /// Iterate over the indices of a sequence. + /// This will work solely because of `serialize::opaque`'s + /// simple encoding of `n: usize` followed by `n` elements. + pub fn seq(mut self) -> impl Iterator { + (0..self.read_usize().unwrap()).map(move |_| { + self.decode() + }) + } + + pub fn seq_mut<'b, T: Decodable>(&'b mut self) -> impl Iterator + 'b { + (0..self.read_usize().unwrap()).map(move |_| { + self.decode() + }) + } } macro_rules! decoder_methods { @@ -104,8 +117,8 @@ macro_rules! decoder_methods { } } -impl<'doc, 'tcx> serialize::Decoder for ::decoder::DecodeContext<'doc, 'tcx> { - type Error = as serialize::Decoder>::Error; +impl<'doc, 'tcx> Decoder for DecodeContext<'doc, 'tcx> { + type Error = as Decoder>::Error; decoder_methods! { read_nil -> (); @@ -311,175 +324,70 @@ impl CrateMetadata { } pub fn load_index(data: &[u8]) -> index::Index { - let index = reader::get_doc(rbml::Doc::new(data), tag_index); - index::Index::from_rbml(index) + index::Index::from_rbml(rbml::Doc::new(data).get(tag_index)) } pub fn crate_rustc_version(data: &[u8]) -> Option { let doc = rbml::Doc::new(data); - reader::maybe_get_doc(doc, tag_rustc_version).map(|s| s.to_string()) + reader::maybe_get_doc(doc, tag_rustc_version).map(|s| { + str::from_utf8(&s.data[s.start..s.end]).unwrap().to_string() + }) } pub fn load_xrefs(data: &[u8]) -> index::DenseIndex { - let index = reader::get_doc(rbml::Doc::new(data), tag_xref_index); + let index = rbml::Doc::new(data).get(tag_xref_index); index::DenseIndex::from_buf(index.data, index.start, index.end) } // Go through each item in the metadata and create a map from that // item's def-key to the item's DefIndex. pub fn load_key_map(data: &[u8]) -> FnvHashMap { - let root_doc = rbml::Doc::new(data); - let items_doc = reader::get_doc(root_doc, tag_items); - let items_data_doc = reader::get_doc(items_doc, tag_items_data); - reader::docs(items_data_doc) - .filter(|&(tag, _)| tag == tag_items_data_item) - .map(|(_, item_doc)| { - // load def-key from item - let key = item_def_key(item_doc); + rbml::Doc::new(data).get(tag_items).get(tag_items_data).children().map(|item_doc| { + // load def-key from item + let key = item_def_key(item_doc); - // load def-index from item; we only encode the full def-id, - // so just pull out the index - let def_id_doc = reader::get_doc(item_doc, tag_def_id); - let def_id = untranslated_def_id(def_id_doc); - assert!(def_id.is_local()); // local to the crate we are decoding, that is - - (key, def_id.index) - }) - .collect() -} - -#[derive(Clone, Copy, Debug, PartialEq)] -enum Family { - ImmStatic, // c - MutStatic, // b - Fn, // f - StaticMethod, // F - Method, // h - Type, // y - Mod, // m - ForeignMod, // n - Enum, // t - Variant(VariantKind), // V, v, w - Impl, // i - DefaultImpl, // d - Trait, // I - Struct(VariantKind), // S, s, u - Union, // U - PublicField, // g - InheritedField, // N - Constant, // C + // load def-index from item + (key, item_doc.get(tag_def_index).decoder().decode()) + }).collect() } fn item_family(item: rbml::Doc) -> Family { - let fam = reader::get_doc(item, tag_items_data_item_family); - match reader::doc_as_u8(fam) as char { - 'C' => Constant, - 'c' => ImmStatic, - 'b' => MutStatic, - 'f' => Fn, - 'F' => StaticMethod, - 'h' => Method, - 'y' => Type, - 'm' => Mod, - 'n' => ForeignMod, - 't' => Enum, - 'V' => Variant(VariantKind::Struct), - 'v' => Variant(VariantKind::Tuple), - 'w' => Variant(VariantKind::Unit), - 'i' => Impl, - 'd' => DefaultImpl, - 'I' => Trait, - 'S' => Struct(VariantKind::Struct), - 's' => Struct(VariantKind::Tuple), - 'u' => Struct(VariantKind::Unit), - 'U' => Union, - 'g' => PublicField, - 'N' => InheritedField, - c => bug!("unexpected family char: {}", c) - } + item.get(tag_items_data_item_family).decoder().decode() } fn item_visibility(item: rbml::Doc) -> ty::Visibility { match reader::maybe_get_doc(item, tag_items_data_item_visibility) { None => ty::Visibility::Public, - Some(visibility_doc) => { - match reader::doc_as_u8(visibility_doc) as char { - 'y' => ty::Visibility::Public, - 'i' => ty::Visibility::PrivateExternal, - _ => bug!("unknown visibility character") - } - } - } -} - -fn fn_constness(item: rbml::Doc) -> hir::Constness { - match reader::maybe_get_doc(item, tag_items_data_item_constness) { - None => hir::Constness::NotConst, - Some(constness_doc) => { - match reader::doc_as_u8(constness_doc) as char { - 'c' => hir::Constness::Const, - 'n' => hir::Constness::NotConst, - _ => bug!("unknown constness character") - } - } + Some(visibility_doc) => visibility_doc.decoder().decode() } } fn item_defaultness(item: rbml::Doc) -> hir::Defaultness { match reader::maybe_get_doc(item, tag_items_data_item_defaultness) { None => hir::Defaultness::Default, // should occur only for default impls on traits - Some(defaultness_doc) => { - match reader::doc_as_u8(defaultness_doc) as char { - 'd' => hir::Defaultness::Default, - 'f' => hir::Defaultness::Final, - _ => bug!("unknown defaultness character") - } - } + Some(defaultness_doc) => defaultness_doc.decoder().decode() } } -fn item_sort(item: rbml::Doc) -> Option { - reader::tagged_docs(item, tag_item_trait_item_sort).nth(0).map(|doc| { - doc.as_str().as_bytes()[0] as char - }) -} - -fn untranslated_def_id(d: rbml::Doc) -> DefId { - let id = reader::doc_as_u64(d); - DefId { - krate: CrateNum::from_u32((id >> 32) as u32), - index: DefIndex::from_u32((id & 0xFFFF_FFFF) as u32) - } -} - -fn translated_def_id(cdata: Cmd, d: rbml::Doc) -> DefId { - let def_id = untranslated_def_id(d); - translate_def_id(cdata, def_id) -} - fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option { - reader::tagged_docs(d, tag_items_data_parent_item).nth(0).map(|did| { - translated_def_id(cdata, did) + reader::maybe_get_doc(d, tag_items_data_parent_item).map(|did| { + let mut dcx = did.decoder(); + dcx.cdata = Some(cdata); + dcx.decode() }) } fn item_require_parent_item(cdata: Cmd, d: rbml::Doc) -> DefId { - translated_def_id(cdata, reader::get_doc(d, tag_items_data_parent_item)) + let mut dcx = d.get(tag_items_data_parent_item).decoder(); + dcx.cdata = Some(cdata); + dcx.decode() } fn item_def_id(d: rbml::Doc, cdata: Cmd) -> DefId { - translated_def_id(cdata, reader::get_doc(d, tag_def_id)) -} - -fn reexports<'a>(d: rbml::Doc<'a>) -> reader::TaggedDocsIterator<'a> { - reader::tagged_docs(d, tag_items_data_item_reexport) -} - -fn variant_disr_val(d: rbml::Doc) -> u64 { - let val_doc = reader::get_doc(d, tag_disr_val); - reader::with_doc_data(val_doc, |data| { - str::from_utf8(data).unwrap().parse().unwrap() - }) + DefId { + krate: cdata.cnum, + index: d.get(tag_def_index).decoder().decode() + } } fn doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) -> Ty<'tcx> { @@ -492,7 +400,7 @@ fn maybe_doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: let mut dcx = tp.decoder(); dcx.tcx = Some(tcx); dcx.cdata = Some(cdata); - Decodable::decode(&mut dcx).unwrap() + dcx.decode() }) } @@ -501,13 +409,7 @@ fn doc_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: C let mut dcx = doc.decoder(); dcx.tcx = Some(tcx); dcx.cdata = Some(cdata); - Decodable::decode(&mut dcx).unwrap() -} - -fn item_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) - -> ty::TraitRef<'tcx> { - let tp = reader::get_doc(doc, tag_item_trait_ref); - doc_trait_ref(tp, tcx, cdata) + dcx.decode() } fn item_name(item: rbml::Doc) -> ast::Name { @@ -516,95 +418,43 @@ fn item_name(item: rbml::Doc) -> ast::Name { fn maybe_item_name(item: rbml::Doc) -> Option { reader::maybe_get_doc(item, tag_paths_data_name).map(|name| { - let string = name.as_str(); - token::intern(string) + name.decoder().decode() }) } -fn family_to_variant_kind<'tcx>(family: Family) -> Option { - match family { - Struct(VariantKind::Struct) | Variant(VariantKind::Struct) | Union => - Some(ty::VariantKind::Struct), - Struct(VariantKind::Tuple) | Variant(VariantKind::Tuple) => - Some(ty::VariantKind::Tuple), - Struct(VariantKind::Unit) | Variant(VariantKind::Unit) => - Some(ty::VariantKind::Unit), - _ => None, - } -} - -fn item_to_def_like(cdata: Cmd, item: rbml::Doc, did: DefId) -> DefLike { - let fam = item_family(item); - match fam { - Constant => { - // Check whether we have an associated const item. - match item_sort(item) { - Some('C') | Some('c') => { - DlDef(Def::AssociatedConst(did)) - } - _ => { - // Regular const item. - DlDef(Def::Const(did)) - } - } +fn item_to_def(cdata: Cmd, item: rbml::Doc, did: DefId) -> Option { + Some(match item_family(item) { + Family::Const => Def::Const(did), + Family::AssociatedConst => Def::AssociatedConst(did), + Family::ImmStatic => Def::Static(did, false), + Family::MutStatic => Def::Static(did, true), + Family::Struct(..) => Def::Struct(did), + Family::Union => Def::Union(did), + Family::Fn => Def::Fn(did), + Family::Method => Def::Method(did), + Family::Type => Def::TyAlias(did), + Family::AssociatedType => { + Def::AssociatedTy(item_require_parent_item(cdata, item), did) } - ImmStatic => DlDef(Def::Static(did, false)), - MutStatic => DlDef(Def::Static(did, true)), - Struct(..) => DlDef(Def::Struct(did)), - Union => DlDef(Def::Union(did)), - Fn => DlDef(Def::Fn(did)), - Method | StaticMethod => { - DlDef(Def::Method(did)) + Family::Mod => Def::Mod(did), + Family::ForeignMod => Def::ForeignMod(did), + Family::Variant(..) => { + Def::Variant(item_require_parent_item(cdata, item), did) } - Type => { - if item_sort(item) == Some('t') { - let trait_did = item_require_parent_item(cdata, item); - DlDef(Def::AssociatedTy(trait_did, did)) - } else { - DlDef(Def::TyAlias(did)) - } + Family::Trait => Def::Trait(did), + Family::Enum => Def::Enum(did), + + Family::Impl | + Family::DefaultImpl | + Family::PublicField | + Family::InheritedField => { + return None } - Mod => DlDef(Def::Mod(did)), - ForeignMod => DlDef(Def::ForeignMod(did)), - Variant(..) => { - let enum_did = item_require_parent_item(cdata, item); - DlDef(Def::Variant(enum_did, did)) - } - Trait => DlDef(Def::Trait(did)), - Enum => DlDef(Def::Enum(did)), - Impl | DefaultImpl => DlImpl(did), - PublicField | InheritedField => DlField, - } -} - -fn parse_unsafety(item_doc: rbml::Doc) -> hir::Unsafety { - let unsafety_doc = reader::get_doc(item_doc, tag_unsafety); - if reader::doc_as_u8(unsafety_doc) != 0 { - hir::Unsafety::Unsafe - } else { - hir::Unsafety::Normal - } -} - -fn parse_paren_sugar(item_doc: rbml::Doc) -> bool { - let paren_sugar_doc = reader::get_doc(item_doc, tag_paren_sugar); - reader::doc_as_u8(paren_sugar_doc) != 0 -} - -fn parse_polarity(item_doc: rbml::Doc) -> hir::ImplPolarity { - let polarity_doc = reader::get_doc(item_doc, tag_polarity); - if reader::doc_as_u8(polarity_doc) != 0 { - hir::ImplPolarity::Negative - } else { - hir::ImplPolarity::Positive - } + }) } fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec { - let names_doc = reader::get_doc(item_doc, tag_associated_type_names); - reader::tagged_docs(names_doc, tag_associated_type_name) - .map(|name_doc| token::intern(name_doc.as_str())) - .collect() + item_doc.get(tag_associated_type_names).decoder().decode() } pub fn get_trait_def<'a, 'tcx>(cdata: Cmd, @@ -613,15 +463,16 @@ pub fn get_trait_def<'a, 'tcx>(cdata: Cmd, { let item_doc = cdata.lookup_item(item_id); let generics = doc_generics(item_doc, tcx, cdata); - let unsafety = parse_unsafety(item_doc); + let unsafety = item_doc.get(tag_unsafety).decoder().decode(); let associated_type_names = parse_associated_type_names(item_doc); - let paren_sugar = parse_paren_sugar(item_doc); + let paren_sugar = item_doc.get(tag_paren_sugar).decoder().decode(); + let trait_ref = doc_trait_ref(item_doc.get(tag_item_trait_ref), tcx, cdata); let def_path = def_path(cdata, item_id).unwrap(); ty::TraitDef::new(unsafety, paren_sugar, generics, - item_trait_ref(item_doc, tcx, cdata), + trait_ref, associated_type_names, def_path.deterministic_hash(tcx)) } @@ -632,16 +483,19 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd, -> ty::AdtDefMaster<'tcx> { fn expect_variant_kind(family: Family) -> ty::VariantKind { - match family_to_variant_kind(family) { - Some(kind) => kind, + match family { + Struct(kind) | Variant(kind) => kind, + Union => ty::VariantKind::Struct, _ => bug!("unexpected family: {:?}", family), } } fn get_enum_variants<'tcx>(cdata: Cmd, doc: rbml::Doc) -> Vec> { - reader::tagged_docs(doc, tag_items_data_item_variant).map(|p| { - let did = translated_def_id(cdata, p); + let mut dcx = doc.get(tag_mod_children).decoder(); + dcx.cdata = Some(cdata); + + dcx.seq().map(|did: DefId| { let item = cdata.lookup_item(did.index); - let disr = variant_disr_val(item); + let disr = item.get(tag_disr_val).decoder().decode(); ty::VariantDefData { did: did, name: item_name(item), @@ -652,23 +506,18 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd, }).collect() } fn get_variant_fields<'tcx>(cdata: Cmd, doc: rbml::Doc) -> Vec> { - let mut index = 0; - reader::tagged_docs(doc, tag_item_field).map(|f| { - let ff = item_family(f); - match ff { - PublicField | InheritedField => {}, - _ => bug!("expected field, found {:?}", ff) + let mut dcx = doc.get(tag_item_fields).decoder(); + dcx.cdata = Some(cdata); + + dcx.seq().map(|did: DefId| { + let f = cdata.lookup_item(did.index); + let vis = match item_family(f) { + PublicField => ty::Visibility::Public, + InheritedField => ty::Visibility::PrivateExternal, + _ => bug!() }; - ty::FieldDefData::new(item_def_id(f, cdata), - item_name(f), - struct_field_family_to_visibility(ff)) - }).chain(reader::tagged_docs(doc, tag_item_unnamed_field).map(|f| { - let ff = item_family(f); - let name = token::with_ident_interner(|interner| interner.intern(index.to_string())); - index += 1; - ty::FieldDefData::new(item_def_id(f, cdata), name, - struct_field_family_to_visibility(ff)) - })).collect() + ty::FieldDefData::new(did, item_name(f), vis) + }).collect() } fn get_struct_variant<'tcx>(cdata: Cmd, doc: rbml::Doc, @@ -692,7 +541,9 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd, Struct(..) => { // Use separate constructor id for unit/tuple structs and reuse did for braced structs. ctor_did = reader::maybe_get_doc(doc, tag_items_data_item_struct_ctor).map(|ctor_doc| { - translated_def_id(cdata, ctor_doc) + let mut dcx = ctor_doc.decoder(); + dcx.cdata = Some(cdata); + dcx.decode() }); (AdtKind::Struct, vec![get_struct_variant(cdata, doc, ctor_did.unwrap_or(did))]) } @@ -784,14 +635,14 @@ pub fn get_type<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) 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| { - Decodable::decode(&mut doc.decoder()).unwrap() + doc.decoder().decode() }) } pub fn get_deprecation(cdata: Cmd, id: DefIndex) -> Option { let item = cdata.lookup_item(id); reader::maybe_get_doc(item, tag_items_data_item_deprecation).map(|doc| { - Decodable::decode(&mut doc.decoder()).unwrap() + doc.decoder().decode() }) } @@ -802,26 +653,21 @@ pub fn get_visibility(cdata: Cmd, id: DefIndex) -> ty::Visibility { pub fn get_parent_impl(cdata: Cmd, id: DefIndex) -> Option { let item = cdata.lookup_item(id); reader::maybe_get_doc(item, tag_items_data_parent_impl).map(|doc| { - translated_def_id(cdata, doc) + let mut dcx = doc.decoder(); + dcx.cdata = Some(cdata); + dcx.decode() }) } pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec { let item = cdata.lookup_item(id); reader::maybe_get_doc(item, tag_items_data_item_repr).map_or(vec![], |doc| { - Decodable::decode(&mut doc.decoder()).unwrap() + doc.decoder().decode() }) } -pub fn get_impl_polarity(cdata: Cmd, id: DefIndex) -> Option { - let item_doc = cdata.lookup_item(id); - let fam = item_family(item_doc); - match fam { - Family::Impl => { - Some(parse_polarity(item_doc)) - } - _ => None - } +pub fn get_impl_polarity(cdata: Cmd, id: DefIndex) -> hir::ImplPolarity { + cdata.lookup_item(id).get(tag_polarity).decoder().decode() } pub fn get_custom_coerce_unsized_kind( @@ -831,7 +677,7 @@ pub fn get_custom_coerce_unsized_kind( { let item_doc = cdata.lookup_item(id); reader::maybe_get_doc(item_doc, tag_impl_coerce_unsized_kind).map(|kind_doc| { - Decodable::decode(&mut kind_doc.decoder()).unwrap() + kind_doc.decoder().decode() }) } @@ -841,44 +687,38 @@ pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd, -> Option> { let item_doc = cdata.lookup_item(id); - let fam = item_family(item_doc); - match fam { - Family::Impl | Family::DefaultImpl => { - reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| { - doc_trait_ref(tp, tcx, cdata) - }) - } - _ => None - } -} - -/// Iterates over the language items in the given crate. -pub fn each_lang_item(cdata: Cmd, mut f: F) -> bool where - 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 index_doc = reader::get_doc(item_doc, tag_lang_items_item_index); - let index = DefIndex::from_u32(reader::doc_as_u32(index_doc)); - - f(index, id) + reader::maybe_get_doc(item_doc, tag_item_trait_ref).map(|tp| { + doc_trait_ref(tp, tcx, cdata) }) } -fn each_child_of_item_or_crate(cdata: Cmd, - item_doc: rbml::Doc, - mut get_crate_data: G, - mut callback: F) where - F: FnMut(DefLike, ast::Name, ty::Visibility), - G: FnMut(CrateNum) -> Rc, -{ - // Iterate over all children. - for child_info_doc in reader::tagged_docs(item_doc, tag_mod_child) { - let child_def_id = translated_def_id(cdata, child_info_doc); +/// Iterates over the language items in the given crate. +pub fn get_lang_items(cdata: Cmd) -> Vec<(DefIndex, usize)> { + rbml::Doc::new(cdata.data()).get(tag_lang_items).decoder().decode() +} + +/// Iterates over each child of the given item. +pub fn each_child_of_item(cdata: Cmd, id: DefIndex, + mut get_crate_data: G, + mut callback: F) + where F: FnMut(Def, ast::Name, ty::Visibility), + G: FnMut(CrateNum) -> Rc, +{ + // Find the item. + let item_doc = match cdata.get_item(id) { + None => return, + Some(item_doc) => item_doc, + }; + + let mut dcx = match reader::maybe_get_doc(item_doc, tag_mod_children) { + Some(doc) => doc.decoder(), + None => return + }; + dcx.cdata = Some(cdata); + + // Iterate over all children. + for child_def_id in dcx.seq_mut::() { // This item may be in yet another crate if it was the child of a // reexport. let crate_data = if child_def_id.krate == cdata.cnum { @@ -894,27 +734,20 @@ fn each_child_of_item_or_crate(cdata: Cmd, // Get the item. if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) { // Hand off the item to the callback. - let child_name = item_name(child_item_doc); - let def_like = item_to_def_like(crate_data, child_item_doc, child_def_id); - let visibility = item_visibility(child_item_doc); - callback(def_like, child_name, visibility); + if let Some(def) = item_to_def(crate_data, child_item_doc, child_def_id) { + let child_name = item_name(child_item_doc); + let visibility = item_visibility(child_item_doc); + callback(def, child_name, visibility); + } } } - for reexport_doc in reexports(item_doc) { - let def_id_doc = reader::get_doc(reexport_doc, - tag_items_data_item_reexport_def_id); - let child_def_id = translated_def_id(cdata, def_id_doc); - - let name_doc = reader::get_doc(reexport_doc, - tag_items_data_item_reexport_name); - let name = name_doc.as_str(); - + for exp in dcx.seq_mut::() { // This reexport may be in yet another crate. - let crate_data = if child_def_id.krate == cdata.cnum { + let crate_data = if exp.def_id.krate == cdata.cnum { None } else { - Some(get_crate_data(child_def_id.krate)) + Some(get_crate_data(exp.def_id.krate)) }; let crate_data = match crate_data { Some(ref cdata) => &**cdata, @@ -922,38 +755,17 @@ fn each_child_of_item_or_crate(cdata: Cmd, }; // Get the item. - if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) { + if let Some(child_item_doc) = crate_data.get_item(exp.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 - // a public re-export. - callback(def_like, token::intern(name), ty::Visibility::Public); + if let Some(def) = item_to_def(crate_data, child_item_doc, exp.def_id) { + // These items have a public visibility because they're part of + // a public re-export. + callback(def, exp.name, ty::Visibility::Public); + } } } } -/// Iterates over each child of the given item. -pub fn each_child_of_item(cdata: Cmd, id: DefIndex, get_crate_data: G, callback: F) - where F: FnMut(DefLike, ast::Name, ty::Visibility), - G: FnMut(CrateNum) -> Rc, -{ - // Find the item. - let item_doc = match cdata.get_item(id) { - None => return, - Some(item_doc) => item_doc, - }; - - each_child_of_item_or_crate(cdata, item_doc, get_crate_data, callback) -} - -/// Iterates over all the top-level crate items. -pub fn each_top_level_item_of_crate(cdata: Cmd, get_crate_data: G, callback: F) - where F: FnMut(DefLike, ast::Name, ty::Visibility), - G: FnMut(CrateNum) -> Rc, -{ - each_child_of_item(cdata, CRATE_DEF_INDEX, get_crate_data, callback) -} - pub fn get_item_name(cdata: Cmd, id: DefIndex) -> ast::Name { item_name(cdata.lookup_item(id)) } @@ -1030,48 +842,31 @@ pub fn maybe_get_item_mir<'a, 'tcx>(cdata: Cmd, let mut dcx = mir_doc.decoder(); dcx.tcx = Some(tcx); dcx.cdata = Some(cdata); - Decodable::decode(&mut dcx).unwrap() + dcx.decode() }) } -fn get_explicit_self<'a, 'tcx>(item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>) +fn get_explicit_self<'a, 'tcx>(cdata: Cmd, item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::ExplicitSelfCategory<'tcx> { - fn get_mutability(ch: u8) -> hir::Mutability { - match ch as char { - 'i' => hir::MutImmutable, - 'm' => hir::MutMutable, - _ => bug!("unknown mutability character: `{}`", ch as char), - } - } + let mut dcx = item.get(tag_item_trait_method_explicit_self).decoder(); + dcx.cdata = Some(cdata); + dcx.tcx = Some(tcx); - let explicit_self_doc = reader::get_doc(item, tag_item_trait_method_explicit_self); - let string = explicit_self_doc.as_str(); - - let explicit_self_kind = string.as_bytes()[0]; - match explicit_self_kind as char { - 's' => ty::ExplicitSelfCategory::Static, - 'v' => ty::ExplicitSelfCategory::ByValue, - '~' => ty::ExplicitSelfCategory::ByBox, - // FIXME(#4846) expl. region - '&' => { - ty::ExplicitSelfCategory::ByReference( - tcx.mk_region(ty::ReEmpty), - get_mutability(string.as_bytes()[1])) - } - _ => bug!("unknown self type code: `{}`", explicit_self_kind as char) - } + dcx.decode() } /// Returns the def IDs of all the items in the given implementation. -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); - match item_sort(doc) { - Some('C') | Some('c') => ty::ConstTraitItemId(def_id), - Some('r') | Some('p') => ty::MethodTraitItemId(def_id), - Some('t') => ty::TypeTraitItemId(def_id), - _ => bug!("unknown impl item sort"), +pub fn get_impl_or_trait_items(cdata: Cmd, impl_id: DefIndex) + -> Vec { + let item = cdata.lookup_item(impl_id); + let mut dcx = item.get(tag_mod_children).decoder(); + dcx.cdata = Some(cdata); + dcx.seq().map(|def_id: DefId| { + match item_to_def(cdata, cdata.lookup_item(def_id.index), def_id) { + Some(Def::AssociatedConst(def_id)) => ty::ConstTraitItemId(def_id), + Some(Def::Method(def_id)) => ty::MethodTraitItemId(def_id), + Some(Def::AssociatedTy(_, def_id)) => ty::TypeTraitItemId(def_id), + def => bug!("get_impl_or_trait_items: invalid def {:?}", def) } }).collect() } @@ -1092,8 +887,7 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a } else { return None; }; - let container_doc = cdata.lookup_item(container_id.index); - let container = match item_family(container_doc) { + let container = match item_family(cdata.lookup_item(container_id.index)) { Trait => TraitContainer(container_id), _ => ImplContainer(container_id), }; @@ -1102,8 +896,8 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a let vis = item_visibility(item_doc); let defaultness = item_defaultness(item_doc); - Some(match item_sort(item_doc) { - sort @ Some('C') | sort @ Some('c') => { + Some(match item_family(item_doc) { + Family::AssociatedConst => { let ty = doc_type(item_doc, tcx, cdata); ty::ConstTraitItem(Rc::new(ty::AssociatedConst { name: name, @@ -1112,10 +906,10 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a defaultness: defaultness, def_id: def_id, container: container, - has_value: sort == Some('C') + has_value: item_doc.get(tag_item_trait_item_has_body).decoder().decode(), })) } - Some('r') | Some('p') => { + Family::Method => { let generics = doc_generics(item_doc, tcx, cdata); let predicates = doc_predicates(item_doc, tcx, cdata, tag_item_predicates); let ity = tcx.lookup_item_type(def_id).ty; @@ -1125,19 +919,22 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a "the type {:?} of the method {:?} is not a function?", ity, name) }; - let explicit_self = get_explicit_self(item_doc, tcx); + let explicit_self = get_explicit_self(cdata, item_doc, tcx); - ty::MethodTraitItem(Rc::new(ty::Method::new(name, - generics, - predicates, - fty, - explicit_self, - vis, - defaultness, - def_id, - container))) + ty::MethodTraitItem(Rc::new(ty::Method { + name: name, + generics: generics, + predicates: predicates, + fty: fty, + explicit_self: explicit_self, + vis: vis, + defaultness: defaultness, + has_body: item_doc.get(tag_item_trait_item_has_body).decoder().decode(), + def_id: def_id, + container: container, + })) } - Some('t') => { + Family::AssociatedType => { let ty = maybe_doc_type(item_doc, tcx, cdata); ty::TypeTraitItem(Rc::new(ty::AssociatedType { name: name, @@ -1152,84 +949,19 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a }) } -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| { - let def_id = item_def_id(mth, cdata); - match item_sort(mth) { - Some('C') | Some('c') => ty::ConstTraitItemId(def_id), - Some('r') | Some('p') => ty::MethodTraitItemId(def_id), - Some('t') => ty::TypeTraitItemId(def_id), - _ => bug!("unknown trait item sort"), - } - }).collect() -} - pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> Vec { let item_doc = cdata.lookup_item(id); - let variance_doc = reader::get_doc(item_doc, tag_item_variances); - Decodable::decode(&mut variance_doc.decoder()).unwrap() -} - -pub fn get_provided_trait_methods<'a, 'tcx>(cdata: Cmd, - id: DefIndex, - tcx: TyCtxt<'a, 'tcx, '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.index); - - if item_sort(mth) == Some('p') { - let trait_item = get_impl_or_trait_item(cdata, did.index, tcx); - if let Some(ty::MethodTraitItem(ref method)) = trait_item { - Some((*method).clone()) - } else { - None - } - } else { - None - } - }).collect() -} - -pub fn get_associated_consts<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> Vec>> { - let item = cdata.lookup_item(id); - - [tag_item_trait_item, tag_item_impl_item].iter().flat_map(|&tag| { - reader::tagged_docs(item, tag).filter_map(|ac_id| { - let did = item_def_id(ac_id, cdata); - let ac_doc = cdata.lookup_item(did.index); - - match item_sort(ac_doc) { - Some('C') | Some('c') => { - let trait_item = get_impl_or_trait_item(cdata, did.index, tcx); - if let Some(ty::ConstTraitItem(ref ac)) = trait_item { - Some((*ac).clone()) - } else { - None - } - } - _ => None - } - }) - }).collect() -} - -pub fn get_variant_kind(cdata: Cmd, node_id: DefIndex) -> Option -{ - let item = cdata.lookup_item(node_id); - family_to_variant_kind(item_family(item)) + item_doc.get(tag_item_variances).decoder().decode() } pub fn get_struct_ctor_def_id(cdata: Cmd, node_id: DefIndex) -> Option { let item = cdata.lookup_item(node_id); - reader::maybe_get_doc(item, tag_items_data_item_struct_ctor). - map(|ctor_doc| translated_def_id(cdata, ctor_doc)) + reader::maybe_get_doc(item, tag_items_data_item_struct_ctor).map(|ctor_doc| { + let mut dcx = ctor_doc.decoder(); + dcx.cdata = Some(cdata); + dcx.decode() + }) } /// If node_id is the constructor of a tuple struct, retrieve the NodeId of @@ -1239,8 +971,12 @@ pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, -> Option { let item = cdata.lookup_item(node_id); - reader::tagged_docs(item, tag_items_data_item_is_tuple_struct_ctor).next().map(|_| { - item_require_parent_item(cdata, item) + reader::maybe_get_doc(item, tag_items_data_item_is_tuple_struct_ctor).and_then(|doc| { + if doc.decoder().decode() { + Some(item_require_parent_item(cdata, item)) + } else { + None + } }) } @@ -1256,39 +992,18 @@ pub fn get_item_attrs(cdata: Cmd, get_attributes(item) } -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 def_id = translated_def_id(cdata, reader::get_doc(field, tag_def_id)); - let attrs = get_attributes(field); - (def_id, attrs) - }).collect() -} - -fn struct_field_family_to_visibility(family: Family) -> ty::Visibility { - match family { - PublicField => ty::Visibility::Public, - InheritedField => ty::Visibility::PrivateExternal, - _ => bug!() - } -} - pub fn get_struct_field_names(cdata: Cmd, id: DefIndex) -> Vec { - let item = cdata.lookup_item(id); - let mut index = 0; - reader::tagged_docs(item, tag_item_field).map(|an_item| { - item_name(an_item) - }).chain(reader::tagged_docs(item, tag_item_unnamed_field).map(|_| { - let name = token::with_ident_interner(|interner| interner.intern(index.to_string())); - index += 1; - name - })).collect() + let mut dcx = cdata.lookup_item(id).get(tag_item_fields).decoder(); + dcx.cdata = Some(cdata); + + dcx.seq().map(|did: DefId| { + item_name(cdata.lookup_item(did.index)) + }).collect() } fn get_attributes(md: rbml::Doc) -> Vec { reader::maybe_get_doc(md, tag_attributes).map_or(vec![], |attrs_doc| { - let mut attrs = Vec::::decode(&mut attrs_doc.decoder()).unwrap(); + let mut attrs = attrs_doc.decoder().decode::>(); // Need new unique IDs: old thread-local IDs won't map to new threads. for attr in attrs.iter_mut() { @@ -1299,22 +1014,6 @@ fn get_attributes(md: rbml::Doc) -> Vec { }) } -fn list_crate_attributes(md: rbml::Doc, hash: &Svh, - out: &mut io::Write) -> io::Result<()> { - write!(out, "=Crate Attributes ({})=\n", *hash)?; - - let r = get_attributes(md); - for attr in &r { - write!(out, "{}\n", pprust::attribute_to_string(attr))?; - } - - write!(out, "\n\n") -} - -pub fn get_crate_attributes(data: &[u8]) -> Vec { - get_attributes(rbml::Doc::new(data)) -} - #[derive(Clone)] pub struct CrateDep { pub cnum: CrateNum, @@ -1324,19 +1023,9 @@ pub struct CrateDep { } pub fn get_crate_deps(data: &[u8]) -> Vec { - let cratedoc = rbml::Doc::new(data); - let depsdoc = reader::get_doc(cratedoc, tag_crate_deps); + let dcx = rbml::Doc::new(data).get(tag_crate_deps).decoder(); - fn docstr(doc: rbml::Doc, tag_: usize) -> String { - let d = reader::get_doc(doc, tag_); - d.as_str().to_string() - } - - reader::tagged_docs(depsdoc, tag_crate_dep).enumerate().map(|(crate_num, depdoc)| { - let name = docstr(depdoc, tag_crate_dep_crate_name); - let hash = Svh::new(reader::doc_as_u64(reader::get_doc(depdoc, tag_crate_dep_hash))); - let doc = reader::get_doc(depdoc, tag_crate_dep_explicitly_linked); - let explicitly_linked = reader::doc_as_u8(doc) != 0; + dcx.seq().enumerate().map(|(crate_num, (name, hash, explicitly_linked))| { CrateDep { cnum: CrateNum::new(crate_num + 1), name: name, @@ -1358,63 +1047,39 @@ fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> { pub fn maybe_get_crate_hash(data: &[u8]) -> Option { let cratedoc = rbml::Doc::new(data); reader::maybe_get_doc(cratedoc, tag_crate_hash).map(|doc| { - Svh::new(reader::doc_as_u64(doc)) + doc.decoder().decode() }) } pub fn get_crate_hash(data: &[u8]) -> Svh { - let cratedoc = rbml::Doc::new(data); - let hashdoc = reader::get_doc(cratedoc, tag_crate_hash); - Svh::new(reader::doc_as_u64(hashdoc)) + rbml::Doc::new(data).get(tag_crate_hash).decoder().decode() } -pub fn maybe_get_crate_name(data: &[u8]) -> Option<&str> { +pub fn maybe_get_crate_name(data: &[u8]) -> Option { let cratedoc = rbml::Doc::new(data); reader::maybe_get_doc(cratedoc, tag_crate_crate_name).map(|doc| { - doc.as_str() + doc.decoder().decode() }) } -pub fn get_crate_disambiguator<'a>(data: &'a [u8]) -> &'a str { - let crate_doc = rbml::Doc::new(data); - let disambiguator_doc = reader::get_doc(crate_doc, tag_crate_disambiguator); - let slice: &'a str = disambiguator_doc.as_str(); - slice +pub fn get_crate_disambiguator(data: &[u8]) -> String { + rbml::Doc::new(data).get(tag_crate_disambiguator).decoder().decode() } pub fn get_crate_triple(data: &[u8]) -> Option { let cratedoc = rbml::Doc::new(data); let triple_doc = reader::maybe_get_doc(cratedoc, tag_crate_triple); - triple_doc.map(|s| s.as_str().to_string()) + triple_doc.map(|s| s.decoder().decode()) } -pub fn get_crate_name(data: &[u8]) -> &str { +pub fn get_crate_name(data: &[u8]) -> String { maybe_get_crate_name(data).expect("no crate name in crate") } pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> { - let hash = get_crate_hash(bytes); - let md = rbml::Doc::new(bytes); - list_crate_attributes(md, &hash, out)?; list_crate_deps(bytes, out) } -// Translates a def_id from an external crate to a def_id for the current -// compilation environment. We use this when trying to load types from -// external crates - if those types further refer to types in other crates -// then we must translate the crate number from that encoded in the external -// 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, index: did.index }; - } - - DefId { - krate: cdata.cnum_map.borrow()[did.krate], - index: did.index - } -} - // Translate a DefId from the current compilation environment to a DefId // for an external crate. fn reverse_translate_def_id(cdata: Cmd, did: DefId) -> Option { @@ -1433,32 +1098,41 @@ pub fn each_inherent_implementation_for_type(cdata: Cmd, where F: FnMut(DefId), { let item_doc = cdata.lookup_item(id); - for impl_doc in reader::tagged_docs(item_doc, tag_items_data_item_inherent_impl) { - if reader::maybe_get_doc(impl_doc, tag_item_trait_ref).is_none() { - callback(item_def_id(impl_doc, cdata)); - } + let mut dcx = item_doc.get(tag_items_data_item_inherent_impls).decoder(); + dcx.cdata = Some(cdata); + + for impl_def_id in dcx.seq() { + callback(impl_def_id); } } pub fn each_implementation_for_trait(cdata: Cmd, - def_id: DefId, + filter: Option, mut callback: F) where F: FnMut(DefId), { // Do a reverse lookup beforehand to avoid touching the crate_num // hash map in the loop below. - if let Some(crate_local_did) = reverse_translate_def_id(cdata, def_id) { - let def_id_u64 = def_to_u64(crate_local_did); + let filter = match filter.map(|def_id| reverse_translate_def_id(cdata, def_id)) { + Some(Some(def_id)) => Some(def_id), + Some(None) => return, + None => None + }; - let impls_doc = reader::get_doc(rbml::Doc::new(cdata.data()), tag_impls); - for trait_doc in reader::tagged_docs(impls_doc, tag_impls_trait) { - let trait_def_id = reader::get_doc(trait_doc, tag_def_id); - if reader::doc_as_u64(trait_def_id) != def_id_u64 { + // FIXME(eddyb) Make this O(1) instead of O(n). + for trait_doc in rbml::Doc::new(cdata.data()).get(tag_impls).children() { + let mut dcx = trait_doc.decoder(); + dcx.cdata = Some(cdata); + + let (krate, index) = dcx.decode(); + if let Some(local_did) = filter { + if (local_did.krate.as_u32(), local_did.index) != (krate, index) { continue; } - for impl_doc in reader::tagged_docs(trait_doc, tag_impls_trait_impl) { - callback(translated_def_id(cdata, impl_doc)); - } + } + + for impl_def_id in dcx.seq() { + callback(impl_def_id); } } } @@ -1479,33 +1153,20 @@ pub fn get_trait_of_item(cdata: Cmd, id: DefIndex) -> Option { pub fn get_native_libraries(cdata: Cmd) -> Vec<(cstore::NativeLibraryKind, String)> { - let libraries = reader::get_doc(rbml::Doc::new(cdata.data()), - tag_native_libraries); - reader::tagged_docs(libraries, tag_native_libraries_lib).map(|lib_doc| { - let kind_doc = reader::get_doc(lib_doc, tag_native_libraries_kind); - let name_doc = reader::get_doc(lib_doc, tag_native_libraries_name); - let kind: cstore::NativeLibraryKind = - cstore::NativeLibraryKind::from_u32(reader::doc_as_u32(kind_doc)).unwrap(); - let name = name_doc.as_str().to_string(); - (kind, name) - }).collect() + rbml::Doc::new(cdata.data()).get(tag_native_libraries).decoder().decode() } pub fn get_plugin_registrar_fn(data: &[u8]) -> Option { reader::maybe_get_doc(rbml::Doc::new(data), tag_plugin_registrar_fn) - .map(|doc| DefIndex::from_u32(reader::doc_as_u32(doc))) + .map(|doc| doc.decoder().decode()) } pub fn each_exported_macro(data: &[u8], mut f: F) where F: FnMut(ast::Name, Vec, Span, String) -> bool, { - let macros = reader::get_doc(rbml::Doc::new(data), tag_macro_defs); - for macro_doc in reader::tagged_docs(macros, tag_macro_def) { - let name = item_name(macro_doc); - let attrs = get_attributes(macro_doc); - let span = get_macro_span(macro_doc); - let body = reader::get_doc(macro_doc, tag_macro_def_body); - if !f(name, attrs, span, body.as_str().to_string()) { + let dcx = rbml::Doc::new(data).get(tag_macro_defs).decoder(); + for (name, attrs, span, body) in dcx.seq() { + if !f(name, attrs, span, body) { break; } } @@ -1513,86 +1174,52 @@ pub fn each_exported_macro(data: &[u8], mut f: F) where pub fn get_derive_registrar_fn(data: &[u8]) -> Option { reader::maybe_get_doc(rbml::Doc::new(data), tag_macro_derive_registrar) - .map(|doc| DefIndex::from_u32(reader::doc_as_u32(doc))) -} - -pub fn get_macro_span(doc: rbml::Doc) -> Span { - let lo_doc = reader::get_doc(doc, tag_macro_def_span_lo); - let lo = BytePos(reader::doc_as_u32(lo_doc)); - let hi_doc = reader::get_doc(doc, tag_macro_def_span_hi); - let hi = BytePos(reader::doc_as_u32(hi_doc)); - return Span { lo: lo, hi: hi, expn_id: NO_EXPANSION }; + .map(|doc| doc.decoder().decode()) } pub fn get_dylib_dependency_formats(cdata: Cmd) -> Vec<(CrateNum, LinkagePreference)> { - let formats = reader::get_doc(rbml::Doc::new(cdata.data()), - tag_dylib_dependency_formats); - let mut result = Vec::new(); + let dcx = rbml::Doc::new(cdata.data()).get(tag_dylib_dependency_formats).decoder(); - debug!("found dylib deps: {}", formats.as_str()); - for spec in formats.as_str().split(',') { - if spec.is_empty() { continue } - let mut split = spec.split(':'); - let cnum = split.next().unwrap(); - let link = split.next().unwrap(); - let cnum = CrateNum::new(cnum.parse().unwrap()); - let cnum = cdata.cnum_map.borrow()[cnum]; - result.push((cnum, if link == "d" { - LinkagePreference::RequireDynamic - } else { - LinkagePreference::RequireStatic - })); - } - return result; + dcx.seq::>().enumerate().flat_map(|(i, link)| { + let cnum = CrateNum::new(i + 1); + link.map(|link| (cdata.cnum_map.borrow()[cnum], link)) + }).collect() } -pub fn get_missing_lang_items(cdata: Cmd) - -> Vec -{ - let items = reader::get_doc(rbml::Doc::new(cdata.data()), tag_lang_items); - reader::tagged_docs(items, tag_lang_items_missing).map(|missing_docs| { - lang_items::LangItem::from_u32(reader::doc_as_u32(missing_docs)).unwrap() - }).collect() +pub fn get_missing_lang_items(cdata: Cmd) -> Vec { + rbml::Doc::new(cdata.data()).get(tag_lang_items_missing).decoder().decode() } 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) => { - reader::tagged_docs(args_doc, tag_method_argument_name).map(|name_doc| { - name_doc.as_str().to_string() - }).collect() - }, + Some(args_doc) => args_doc.decoder().decode(), None => vec![], } } pub fn get_reachable_ids(cdata: Cmd) -> Vec { - let items = reader::get_doc(rbml::Doc::new(cdata.data()), - tag_reachable_ids); - reader::tagged_docs(items, tag_reachable_id).map(|doc| { + let dcx = rbml::Doc::new(cdata.data()).get(tag_reachable_ids).decoder(); + + dcx.seq().map(|index| { DefId { krate: cdata.cnum, - index: DefIndex::from_u32(reader::doc_as_u32(doc)), + index: index, } }).collect() } -pub fn is_typedef(cdata: Cmd, id: DefIndex) -> bool { - let item_doc = cdata.lookup_item(id); - match item_family(item_doc) { - Type => true, - _ => false, - } -} - 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, - hir::Constness::NotConst => false, + match reader::maybe_get_doc(cdata.lookup_item(id), tag_items_data_item_constness) { + None => false, + Some(doc) => { + match doc.decoder().decode() { + hir::Constness::Const => true, + hir::Constness::NotConst => false, + } + } } } @@ -1628,40 +1255,15 @@ pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool { item_family(parent_item_doc) == ForeignMod } -pub fn is_impl(cdata: Cmd, id: DefIndex) -> bool { - let item_doc = cdata.lookup_item(id); - match item_family(item_doc) { - Impl => true, - _ => false, - } -} - fn doc_generics<'a, 'tcx>(base_doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) -> &'tcx ty::Generics<'tcx> { - let mut dcx = reader::get_doc(base_doc, tag_item_generics).decoder(); + let mut dcx = base_doc.get(tag_item_generics).decoder(); dcx.tcx = Some(tcx); dcx.cdata = Some(cdata); - tcx.alloc_generics(Decodable::decode(&mut dcx).unwrap()) -} - -fn doc_predicate<'a, 'tcx>(cdata: Cmd, - doc: rbml::Doc, - tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> ty::Predicate<'tcx> -{ - let predicate_pos = cdata.xref_index.lookup( - cdata.data(), reader::doc_as_u32(doc)).unwrap() as usize; - let mut dcx = rbml::Doc { - data: cdata.data(), - start: predicate_pos, - end: cdata.data().len(), - }.decoder(); - dcx.tcx = Some(tcx); - dcx.cdata = Some(cdata); - Decodable::decode(&mut dcx).unwrap() + tcx.alloc_generics(dcx.decode()) } fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc, @@ -1670,51 +1272,50 @@ fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc, tag: usize) -> ty::GenericPredicates<'tcx> { - let doc = reader::get_doc(base_doc, tag); + let mut dcx = base_doc.get(tag).decoder(); + dcx.cdata = Some(cdata); ty::GenericPredicates { - parent: item_parent_item(cdata, doc), - predicates: reader::tagged_docs(doc, tag_predicate).map(|predicate_doc| { - doc_predicate(cdata, predicate_doc, tcx) + parent: dcx.decode(), + predicates: dcx.seq().map(|offset| { + let predicate_pos = cdata.xref_index.lookup( + cdata.data(), offset).unwrap() as usize; + let mut dcx = rbml::Doc { + data: cdata.data(), + start: predicate_pos, + end: cdata.data().len(), + }.decoder(); + dcx.tcx = Some(tcx); + dcx.cdata = Some(cdata); + dcx.decode() }).collect() } } 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 + cdata.lookup_item(trait_id).get(tag_defaulted_trait).decoder().decode() } 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 + item_family(cdata.lookup_item(impl_id)) == Family::DefaultImpl } pub fn get_imported_filemaps(metadata: &[u8]) -> Vec { - let crate_doc = rbml::Doc::new(metadata); - let cm_doc = reader::get_doc(crate_doc, tag_codemap); - - reader::tagged_docs(cm_doc, tag_codemap_filemap).map(|filemap_doc| { - Decodable::decode(&mut filemap_doc.decoder()).unwrap() - }).collect() + rbml::Doc::new(metadata).get(tag_codemap).decoder().decode() } 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); - ty::ClosureKind::decode(&mut closure_kind_doc.decoder()).unwrap() + cdata.lookup_item(closure_id).get(tag_items_closure_kind).decoder().decode() } pub fn closure_ty<'a, 'tcx>(cdata: Cmd, closure_id: DefIndex, tcx: TyCtxt<'a, 'tcx, '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); + let closure_ty_doc = closure_doc.get(tag_items_closure_ty); let mut dcx = closure_ty_doc.decoder(); dcx.tcx = Some(tcx); dcx.cdata = Some(cdata); - Decodable::decode(&mut dcx).unwrap() + dcx.decode() } pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey { @@ -1726,10 +1327,8 @@ pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey { fn item_def_key(item_doc: rbml::Doc) -> hir_map::DefKey { match reader::maybe_get_doc(item_doc, tag_def_key) { Some(def_key_doc) => { - let simple_key = def_key::DefKey::decode(&mut def_key_doc.decoder()).unwrap(); - let name = reader::maybe_get_doc(item_doc, tag_paths_data_name).map(|name| { - token::intern(name.as_str()).as_str() - }); + let simple_key = def_key_doc.decoder().decode(); + let name = maybe_item_name(item_doc).map(|name| name.as_str()); def_key::recover_def_key(simple_key, name) } None => { @@ -1753,11 +1352,5 @@ pub fn def_path(cdata: Cmd, id: DefIndex) -> Option { } pub fn get_panic_strategy(data: &[u8]) -> PanicStrategy { - let crate_doc = rbml::Doc::new(data); - let strat_doc = reader::get_doc(crate_doc, tag_panic_strategy); - match reader::doc_as_u8(strat_doc) { - b'U' => PanicStrategy::Unwind, - b'A' => PanicStrategy::Abort, - b => panic!("unknown panic strategy in metadata: {}", b), - } + rbml::Doc::new(data).get(tag_panic_strategy).decoder().decode() } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index e414275f8b4..7b4a6972d22 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -20,7 +20,7 @@ use decoder; use def_key; use index::{self, IndexData}; -use middle::cstore::{InlinedItemRef, LinkMeta}; +use middle::cstore::{InlinedItemRef, LinkMeta, LinkagePreference}; use rustc::hir::def; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; use middle::dependency_format::Linkage; @@ -28,24 +28,22 @@ use rustc::dep_graph::DepNode; use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; -use rustc::hir::svh::Svh; use rustc::mir::mir_map::MirMap; -use rustc::session::config::{self, PanicStrategy, CrateTypeRustcMacro}; +use rustc::session::config::{self, CrateTypeRustcMacro}; use rustc::util::nodemap::{FnvHashMap, NodeSet}; use rustc_serialize::{Encodable, Encoder, SpecializedEncoder, opaque}; -use rustc_serialize as serialize; use std::cell::RefCell; use std::intrinsics; use std::io::prelude::*; use std::io::Cursor; +use std::mem; use std::ops::{Deref, DerefMut}; use std::rc::Rc; use std::u32; use syntax::ast::{self, NodeId, Name, CRATE_NODE_ID}; use syntax::attr; use syntax; -use syntax_pos::BytePos; use rbml; use rustc::hir::{self, PatKind}; @@ -53,7 +51,7 @@ use rustc::hir::intravisit::Visitor; use rustc::hir::intravisit; use rustc::hir::map::DefKey; -use super::index_builder::{FromId, IndexBuilder, ItemContentBuilder, Untracked, XRef}; +use super::index_builder::{FromId, IndexBuilder, Untracked}; pub struct EncodeContext<'a, 'tcx: 'a> { rbml_w: rbml::writer::Encoder<'a>, @@ -61,11 +59,17 @@ pub struct EncodeContext<'a, 'tcx: 'a> { reexports: &'a def::ExportMap, link_meta: &'a LinkMeta, cstore: &'a cstore::CStore, - type_shorthands: RefCell, usize>>, reachable: &'a NodeSet, mir_map: &'a MirMap<'tcx>, + + type_shorthands: RefCell, usize>>, + xrefs: FnvHashMap, u32>, // sequentially-assigned } +/// "interned" entries referenced by id +#[derive(PartialEq, Eq, Hash)] +enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } + impl<'a, 'tcx> Deref for EncodeContext<'a, 'tcx> { type Target = rbml::writer::Encoder<'a>; fn deref(&self) -> &Self::Target { @@ -87,8 +91,8 @@ macro_rules! encoder_methods { } } -impl<'a, 'tcx> serialize::Encoder for ::encoder::EncodeContext<'a, 'tcx> { - type Error = as serialize::Encoder>::Error; +impl<'a, 'tcx> Encoder for EncodeContext<'a, 'tcx> { + type Error = as Encoder>::Error; fn emit_nil(&mut self) -> Result<(), Self::Error> { Ok(()) @@ -146,12 +150,35 @@ impl<'a, 'tcx> SpecializedEncoder> for EncodeContext<'a, 'tcx> { } } -fn encode_name(ecx: &mut EncodeContext, name: Name) { - ecx.wr_tagged_str(tag_paths_data_name, &name.as_str()); +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { + fn seq(&mut self, iter: I, mut f: F) + where I: IntoIterator, + I::IntoIter: ExactSizeIterator, + F: FnMut(&mut Self, I::Item) -> T, + T: Encodable { + let iter = iter.into_iter(); + self.emit_seq(iter.len(), move |ecx| { + for (i, elem) in iter.enumerate() { + ecx.emit_seq_elt(i, |ecx| { + f(ecx, elem).encode(ecx) + })?; + } + Ok(()) + }).unwrap(); + } } -fn encode_def_id(ecx: &mut EncodeContext, id: DefId) { - ecx.wr_tagged_u64(tag_def_id, def_to_u64(id)); +fn encode_name(ecx: &mut EncodeContext, name: Name) { + ecx.start_tag(tag_paths_data_name); + name.encode(ecx).unwrap(); + ecx.end_tag(); +} + +fn encode_def_id(ecx: &mut EncodeContext, def_id: DefId) { + assert!(def_id.is_local()); + ecx.start_tag(tag_def_index); + def_id.index.encode(ecx).unwrap(); + ecx.end_tag(); } fn encode_def_key(ecx: &mut EncodeContext, key: DefKey) { @@ -178,16 +205,10 @@ fn encode_trait_ref<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>, } // Item info table encoding -fn encode_family(ecx: &mut EncodeContext, c: char) { - ecx.wr_tagged_u8(tag_items_data_item_family, c as u8); -} - -pub fn def_to_u64(did: DefId) -> u64 { - (did.krate.as_u32() as u64) << 32 | (did.index.as_u32() as u64) -} - -pub fn def_to_string(_tcx: TyCtxt, did: DefId) -> String { - format!("{}:{}", did.krate, did.index.as_usize()) +fn encode_family(ecx: &mut EncodeContext, f: Family) { + ecx.start_tag(tag_items_data_item_family); + f.encode(ecx).unwrap(); + ecx.end_tag(); } fn encode_item_variances(ecx: &mut EncodeContext, id: NodeId) { @@ -197,7 +218,7 @@ fn encode_item_variances(ecx: &mut EncodeContext, id: NodeId) { ecx.end_tag(); } -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_bounds_and_type_for_item(&mut self, def_id: DefId) { let tcx = self.tcx; self.encode_bounds_and_type(&tcx.lookup_item_type(def_id), @@ -210,44 +231,31 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { self.encode_generics(&scheme.generics, &predicates); self.encode_type(scheme.ty); } -} -fn encode_variant_id(ecx: &mut EncodeContext, vid: DefId) { - let id = def_to_u64(vid); - ecx.wr_tagged_u64(tag_items_data_item_variant, id); - ecx.wr_tagged_u64(tag_mod_child, id); -} - -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { fn encode_type(&mut self, typ: Ty<'tcx>) { self.start_tag(tag_items_data_item_type); - typ.encode(self.ecx).unwrap(); + typ.encode(self).unwrap(); self.end_tag(); } fn encode_disr_val(&mut self, disr_val: ty::Disr) { - // convert to u64 so just the number is printed, without any type info - self.wr_tagged_str(tag_disr_val, &disr_val.to_u64_unchecked().to_string()); + self.start_tag(tag_disr_val); + disr_val.to_u64_unchecked().encode(self).unwrap(); + self.end_tag(); } fn encode_parent_item(&mut self, id: DefId) { - self.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(id)); + self.start_tag(tag_items_data_parent_item); + id.encode(self).unwrap(); + self.end_tag(); } - fn encode_struct_fields(&mut self, - variant: ty::VariantDef) { - for f in &variant.fields { - if variant.kind == ty::VariantKind::Tuple { - self.start_tag(tag_item_unnamed_field); - } else { - self.start_tag(tag_item_field); - encode_name(self, f.name); - } - self.encode_struct_field_family(f.vis); - encode_def_id(self, f.did); - self.end_tag(); - } + fn encode_variant_fields(&mut self, + variant: ty::VariantDef) { + self.start_tag(tag_item_fields); + self.seq(&variant.fields, |_, f| f.did); + self.end_tag(); } } @@ -258,13 +266,13 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { self.encode_fields(enum_did); for (i, variant) in def.variants.iter().enumerate() { self.record(variant.did, - ItemContentBuilder::encode_enum_variant_info, + EncodeContext::encode_enum_variant_info, (enum_did, Untracked(i))); } } } -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { /// Encode data for the given variant of the given ADT. The /// index of the variant is untracked: this is ok because we /// will have to lookup the adt-def by its id, and that gives us @@ -278,11 +286,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { let variant = &def.variants[index]; let vid = variant.did; encode_def_id_and_key(self, vid); - encode_family(self, match variant.kind { - ty::VariantKind::Struct => 'V', - ty::VariantKind::Tuple => 'v', - ty::VariantKind::Unit => 'w', - }); + encode_family(self, Family::Variant(variant.kind)); encode_name(self, variant.name); self.encode_parent_item(enum_did); @@ -299,51 +303,35 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_stability(self, stab); encode_deprecation(self, depr); - self.encode_struct_fields(variant); + self.encode_variant_fields(variant); self.encode_disr_val(variant.disr_val); self.encode_bounds_and_type_for_item(vid); } } -fn encode_reexports(ecx: &mut EncodeContext, id: NodeId) { - debug!("(encoding info for module) encoding reexports for {}", id); - match ecx.reexports.get(&id) { - Some(exports) => { - debug!("(encoding info for module) found reexports for {}", id); - for exp in exports { - debug!("(encoding info for module) reexport '{}' ({:?}) for \ - {}", - exp.name, - exp.def_id, - id); - ecx.start_tag(tag_items_data_item_reexport); - ecx.wr_tagged_u64(tag_items_data_item_reexport_def_id, - def_to_u64(exp.def_id)); - ecx.wr_tagged_str(tag_items_data_item_reexport_name, - &exp.name.as_str()); - ecx.end_tag(); - } - }, - None => debug!("(encoding info for module) found no reexports for {}", id), - } -} - -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_mod(&mut self, FromId(id, (md, attrs, name, vis)): FromId<(&hir::Mod, &[ast::Attribute], Name, &hir::Visibility)>) { let tcx = self.tcx; encode_def_id_and_key(self, tcx.map.local_def_id(id)); - encode_family(self, 'm'); + encode_family(self, Family::Mod); encode_name(self, name); debug!("(encoding info for module) encoding info for module ID {}", id); // Encode info about all the module children. - for item_id in &md.item_ids { - self.wr_tagged_u64(tag_mod_child, - def_to_u64(tcx.map.local_def_id(item_id.id))); + self.start_tag(tag_mod_children); + self.seq(&md.item_ids, |_, item_id| { + tcx.map.local_def_id(item_id.id) + }); + + // Encode the reexports of this module, if this module is public. + match self.reexports.get(&id) { + Some(exports) if *vis == hir::Public => exports.encode(self).unwrap(), + _ => <[def::Export]>::encode(&[], self).unwrap() } + self.end_tag(); self.encode_visibility(vis); @@ -352,22 +340,27 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_stability(self, stab); encode_deprecation(self, depr); - // Encode the reexports of this module, if this module is public. - if *vis == hir::Public { - debug!("(encoding info for module) encoding reexports for {}", id); - encode_reexports(self, id); - } encode_attributes(self, attrs); } fn encode_struct_field_family(&mut self, visibility: ty::Visibility) { - encode_family(self, if visibility.is_public() { 'g' } else { 'N' }); + encode_family(self, if visibility.is_public() { + Family::PublicField + } else { + Family::InheritedField + }); } fn encode_visibility(&mut self, visibility: T) { - let ch = if visibility.is_public() { 'y' } else { 'i' }; - self.wr_tagged_u8(tag_items_data_item_visibility, ch as u8); + let vis = if visibility.is_public() { + ty::Visibility::Public + } else { + ty::Visibility::PrivateExternal + }; + self.start_tag(tag_items_data_item_visibility); + vis.encode(self).unwrap(); + self.end_tag(); } } @@ -389,54 +382,14 @@ impl HasVisibility for ty::Visibility { fn encode_constness(ecx: &mut EncodeContext, constness: hir::Constness) { ecx.start_tag(tag_items_data_item_constness); - let ch = match constness { - hir::Constness::Const => 'c', - hir::Constness::NotConst => 'n', - }; - ecx.wr_str(&ch.to_string()); + constness.encode(ecx).unwrap(); ecx.end_tag(); } fn encode_defaultness(ecx: &mut EncodeContext, defaultness: hir::Defaultness) { - let ch = match defaultness { - hir::Defaultness::Default => 'd', - hir::Defaultness::Final => 'f', - }; - ecx.wr_tagged_u8(tag_items_data_item_defaultness, ch as u8); -} - -fn encode_explicit_self(ecx: &mut EncodeContext, - explicit_self: &ty::ExplicitSelfCategory) { - let tag = tag_item_trait_method_explicit_self; - - // Encode the base self type. - match *explicit_self { - ty::ExplicitSelfCategory::Static => { - ecx.wr_tagged_bytes(tag, &['s' as u8]); - } - ty::ExplicitSelfCategory::ByValue => { - ecx.wr_tagged_bytes(tag, &['v' as u8]); - } - ty::ExplicitSelfCategory::ByBox => { - ecx.wr_tagged_bytes(tag, &['~' as u8]); - } - ty::ExplicitSelfCategory::ByReference(_, m) => { - // FIXME(#4846) encode custom lifetime - let ch = encode_mutability(m); - ecx.wr_tagged_bytes(tag, &['&' as u8, ch]); - } - } - - fn encode_mutability(m: hir::Mutability) -> u8 { - match m { - hir::MutImmutable => 'i' as u8, - hir::MutMutable => 'm' as u8, - } - } -} - -fn encode_item_sort(ecx: &mut EncodeContext, sort: char) { - ecx.wr_tagged_u8(tag_item_trait_item_sort, sort as u8); + ecx.start_tag(tag_items_data_item_defaultness); + defaultness.encode(ecx).unwrap(); + ecx.end_tag(); } impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { @@ -446,14 +399,14 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { for (variant_index, variant) in def.variants.iter().enumerate() { for (field_index, field) in variant.fields.iter().enumerate() { self.record(field.did, - ItemContentBuilder::encode_field, + EncodeContext::encode_field, (adt_def_id, Untracked((variant_index, field_index)))); } } } } -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { /// Encode data for the given field of the given variant of the /// given ADT. The indices of the variant/field are untracked: /// this is ok because we will have to lookup the adt-def by its @@ -476,6 +429,10 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { self.encode_bounds_and_type_for_item(field.did); encode_def_id_and_key(self, field.did); + let variant_id = tcx.map.as_local_node_id(variant.did).unwrap(); + let variant_data = tcx.map.expect_variant_data(variant_id); + encode_attributes(self, &variant_data.fields()[field_index].attrs); + let stab = tcx.lookup_stability(field.did); let depr = tcx.lookup_deprecation(field.did); encode_stability(self, stab); @@ -491,11 +448,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { let item = tcx.map.expect_item(struct_node_id); let ctor_def_id = tcx.map.local_def_id(ctor_node_id); encode_def_id_and_key(self, ctor_def_id); - encode_family(self, match variant.kind { - ty::VariantKind::Struct => 'S', - ty::VariantKind::Tuple => 's', - ty::VariantKind::Unit => 'u', - }); + encode_family(self, Family::Struct(variant.kind)); self.encode_bounds_and_type_for_item(ctor_def_id); encode_name(self, item.name); self.encode_parent_item(struct_def_id); @@ -510,7 +463,9 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { // definition, but without this there is no way for them // to tell that they actually have a ctor rather than a // normal function - self.wr_tagged_bytes(tag_items_data_item_is_tuple_struct_ctor, &[]); + self.start_tag(tag_items_data_item_is_tuple_struct_ctor); + true.encode(self).unwrap(); + self.end_tag(); } fn encode_generics(&mut self, @@ -518,7 +473,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { predicates: &ty::GenericPredicates<'tcx>) { self.start_tag(tag_item_generics); - generics.encode(self.ecx).unwrap(); + generics.encode(self).unwrap(); self.end_tag(); self.encode_predicates(predicates, tag_item_predicates); } @@ -527,13 +482,10 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { predicates: &ty::GenericPredicates<'tcx>, tag: usize) { self.start_tag(tag); - if let Some(def_id) = predicates.parent { - self.wr_tagged_u64(tag_items_data_parent_item, def_to_u64(def_id)); - } - for predicate in &predicates.predicates { - let xref = self.add_xref(XRef::Predicate(predicate.clone())); - self.wr_tagged_u32(tag_predicate, xref); - } + predicates.parent.encode(self).unwrap(); + self.seq(&predicates.predicates, |ecx, predicate| { + ecx.add_xref(XRef::Predicate(predicate.clone())) + }); self.end_tag(); } @@ -542,13 +494,12 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_name(self, method_ty.name); self.encode_generics(&method_ty.generics, &method_ty.predicates); self.encode_visibility(method_ty.vis); - encode_explicit_self(self, &method_ty.explicit_self); - match method_ty.explicit_self { - ty::ExplicitSelfCategory::Static => { - encode_family(self, STATIC_METHOD_FAMILY); - } - _ => encode_family(self, METHOD_FAMILY) - } + + self.start_tag(tag_item_trait_method_explicit_self); + method_ty.explicit_self.encode(self).unwrap(); + self.end_tag(); + + encode_family(self, Family::Method); } fn encode_info_for_trait_item(&mut self, @@ -563,79 +514,47 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_stability(self, stab); encode_deprecation(self, depr); - let trait_item_type = - tcx.impl_or_trait_item(item_def_id); - let is_nonstatic_method; - match trait_item_type { + match tcx.impl_or_trait_item(item_def_id) { ty::ConstTraitItem(associated_const) => { encode_name(self, associated_const.name); - encode_def_id_and_key(self, associated_const.def_id); + encode_def_id_and_key(self, item_def_id); self.encode_visibility(associated_const.vis); - encode_family(self, 'C'); - - self.encode_bounds_and_type_for_item(associated_const.def_id); - - is_nonstatic_method = false; + encode_family(self, Family::AssociatedConst); + self.encode_bounds_and_type_for_item(item_def_id); } ty::MethodTraitItem(method_ty) => { - let method_def_id = item_def_id; - self.encode_method_ty_fields(&method_ty); - - match method_ty.explicit_self { - ty::ExplicitSelfCategory::Static => { - encode_family(self, STATIC_METHOD_FAMILY); - } - _ => { - encode_family(self, METHOD_FAMILY); - } - } - self.encode_bounds_and_type_for_item(method_def_id); - - is_nonstatic_method = method_ty.explicit_self != - ty::ExplicitSelfCategory::Static; + self.encode_bounds_and_type_for_item(item_def_id); } ty::TypeTraitItem(associated_type) => { encode_name(self, associated_type.name); - encode_def_id_and_key(self, associated_type.def_id); - encode_item_sort(self, 't'); - encode_family(self, 'y'); + encode_def_id_and_key(self, item_def_id); + encode_family(self, Family::AssociatedType); if let Some(ty) = associated_type.ty { self.encode_type(ty); } - - is_nonstatic_method = false; } } encode_attributes(self, &trait_item.attrs); match trait_item.node { hir::ConstTraitItem(_, ref default) => { - if default.is_some() { - encode_item_sort(self, 'C'); - } else { - encode_item_sort(self, 'c'); - } + self.start_tag(tag_item_trait_item_has_body); + default.is_some().encode(self).unwrap(); + self.end_tag(); encode_inlined_item(self, InlinedItemRef::TraitItem(trait_def_id, trait_item)); self.encode_mir(item_def_id); } hir::MethodTraitItem(ref sig, ref body) => { - // If this is a static method, we've already - // encoded self. - if is_nonstatic_method { - self.encode_bounds_and_type_for_item(item_def_id); - } + self.start_tag(tag_item_trait_item_has_body); + body.is_some().encode(self).unwrap(); + self.end_tag(); - if body.is_some() { - encode_item_sort(self, 'p'); - self.encode_mir(item_def_id); - } else { - encode_item_sort(self, 'r'); - } + self.encode_mir(item_def_id); self.encode_method_argument_names(&sig.decl); } @@ -654,7 +573,6 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { } ty::MethodTraitItem(ref method_type) => { self.encode_info_for_method(&method_type, - false, impl_id, ast_item) } @@ -678,10 +596,13 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_def_id_and_key(self, associated_const.def_id); encode_name(self, associated_const.name); self.encode_visibility(associated_const.vis); - encode_family(self, 'C'); + encode_family(self, Family::AssociatedConst); self.encode_parent_item(tcx.map.local_def_id(parent_id)); - encode_item_sort(self, 'C'); + + self.start_tag(tag_item_trait_item_has_body); + true.encode(self).unwrap(); + self.end_tag(); self.encode_bounds_and_type_for_item(associated_const.def_id); @@ -702,7 +623,6 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { fn encode_info_for_method(&mut self, m: &ty::Method<'tcx>, - is_default_impl: bool, parent_id: NodeId, impl_item_opt: Option<&hir::ImplItem>) { let tcx = self.tcx; @@ -711,7 +631,10 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { m.name); self.encode_method_ty_fields(m); self.encode_parent_item(tcx.map.local_def_id(parent_id)); - encode_item_sort(self, 'r'); + + self.start_tag(tag_item_trait_item_has_body); + true.encode(self).unwrap(); + self.end_tag(); let stab = tcx.lookup_stability(m.def_id); let depr = tcx.lookup_deprecation(m.def_id); @@ -725,8 +648,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_attributes(self, &impl_item.attrs); let generics = tcx.lookup_generics(m.def_id); let types = generics.parent_types as usize + generics.types.len(); - let needs_inline = types > 0 || is_default_impl || - attr::requests_inline(&impl_item.attrs); + let needs_inline = types > 0 || attr::requests_inline(&impl_item.attrs); if sig.constness == hir::Constness::Const { encode_inlined_item( self, @@ -755,9 +677,8 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_def_id_and_key(self, associated_type.def_id); encode_name(self, associated_type.name); self.encode_visibility(associated_type.vis); - encode_family(self, 'y'); + encode_family(self, Family::AssociatedType); self.encode_parent_item(tcx.map.local_def_id(parent_id)); - encode_item_sort(self, 't'); let stab = tcx.lookup_stability(associated_type.def_id); let depr = tcx.lookup_deprecation(associated_type.def_id); @@ -777,15 +698,15 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { fn encode_method_argument_names(&mut self, decl: &hir::FnDecl) { self.start_tag(tag_method_argument_names); - for arg in &decl.inputs { - let tag = tag_method_argument_name; + + self.seq(&decl.inputs, |_, arg| { if let PatKind::Binding(_, ref path1, _) = arg.pat.node { - let name = path1.node.as_str(); - self.wr_tagged_bytes(tag, name.as_bytes()); + path1.node } else { - self.wr_tagged_bytes(tag, &[]); + syntax::parse::token::intern("") } - } + }); + self.end_tag(); } @@ -797,36 +718,28 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { attr)); } self.start_tag(tag_items_data_item_repr); - repr_attrs.encode(self.ecx); + repr_attrs.encode(self); self.end_tag(); } fn encode_mir(&mut self, def_id: DefId) { if let Some(mir) = self.mir_map.map.get(&def_id) { self.start_tag(tag_mir as usize); - mir.encode(self.ecx); + mir.encode(self); self.end_tag(); } } } -const FN_FAMILY: char = 'f'; -const STATIC_METHOD_FAMILY: char = 'F'; -const METHOD_FAMILY: char = 'h'; - // Encodes the inherent implementations of a structure, enumeration, or trait. fn encode_inherent_implementations(ecx: &mut EncodeContext, def_id: DefId) { + ecx.start_tag(tag_items_data_item_inherent_impls); match ecx.tcx.inherent_impls.borrow().get(&def_id) { - None => {} - Some(implementations) => { - for &impl_def_id in implementations.iter() { - ecx.start_tag(tag_items_data_item_inherent_impl); - encode_def_id(ecx, impl_def_id); - ecx.end_tag(); - } - } + None => <[DefId]>::encode(&[], ecx).unwrap(), + Some(implementations) => implementations.encode(ecx).unwrap() } + ecx.end_tag(); } fn encode_stability(ecx: &mut EncodeContext, stab_opt: Option<&attr::Stability>) { @@ -845,37 +758,35 @@ fn encode_deprecation(ecx: &mut EncodeContext, depr_opt: Option) { - parent_opt.map(|parent| { - ecx.wr_tagged_u64(tag_items_data_parent_impl, def_to_u64(parent)); - }); -} - -fn encode_xrefs<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>, - xrefs: FnvHashMap, u32>) -{ - let mut xref_positions = vec![0; xrefs.len()]; - - // Encode XRefs sorted by their ID - let mut sorted_xrefs: Vec<_> = xrefs.into_iter().collect(); - sorted_xrefs.sort_by_key(|&(_, id)| id); - - ecx.start_tag(tag_xref_data); - for (xref, id) in sorted_xrefs.into_iter() { - xref_positions[id as usize] = ecx.mark_stable_position() as u32; - match xref { - XRef::Predicate(p) => p.encode(ecx).unwrap() - } +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { + fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 { + let old_len = self.xrefs.len() as u32; + *self.xrefs.entry(xref).or_insert(old_len) } - ecx.mark_stable_position(); - ecx.end_tag(); - ecx.start_tag(tag_xref_index); - index::write_dense_index(xref_positions, &mut ecx.opaque.cursor); - ecx.end_tag(); -} + fn encode_xrefs(&mut self) { + let xrefs = mem::replace(&mut self.xrefs, Default::default()); + let mut xref_positions = vec![0; xrefs.len()]; + + // Encode XRefs sorted by their ID + let mut sorted_xrefs: Vec<_> = xrefs.into_iter().collect(); + sorted_xrefs.sort_by_key(|&(_, id)| id); + + self.start_tag(tag_xref_data); + for (xref, id) in sorted_xrefs.into_iter() { + xref_positions[id as usize] = self.mark_stable_position() as u32; + match xref { + XRef::Predicate(p) => p.encode(self).unwrap() + } + } + self.mark_stable_position(); + self.end_tag(); + + self.start_tag(tag_xref_index); + index::write_dense_index(xref_positions, &mut self.opaque.cursor); + self.end_tag(); + } -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { fn encode_info_for_item(&mut self, (def_id, item): (DefId, &hir::Item)) { let tcx = self.tcx; @@ -893,11 +804,11 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { match item.node { hir::ItemStatic(_, m, _) => { encode_def_id_and_key(self, def_id); - if m == hir::MutMutable { - encode_family(self, 'b'); + encode_family(self, if m == hir::MutMutable { + Family::MutStatic } else { - encode_family(self, 'c'); - } + Family::ImmStatic + }); self.encode_bounds_and_type_for_item(def_id); encode_name(self, item.name); self.encode_visibility(vis); @@ -907,7 +818,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { } hir::ItemConst(..) => { encode_def_id_and_key(self, def_id); - encode_family(self, 'C'); + encode_family(self, Family::Const); self.encode_bounds_and_type_for_item(def_id); encode_name(self, item.name); encode_attributes(self, &item.attrs); @@ -919,7 +830,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { } hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { encode_def_id_and_key(self, def_id); - encode_family(self, FN_FAMILY); + encode_family(self, Family::Fn); let tps_len = generics.ty_params.len(); self.encode_bounds_and_type_for_item(def_id); encode_name(self, item.name); @@ -942,22 +853,24 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { } hir::ItemForeignMod(ref fm) => { encode_def_id_and_key(self, def_id); - encode_family(self, 'n'); + encode_family(self, Family::ForeignMod); encode_name(self, item.name); // Encode all the items in self module. - for foreign_item in &fm.items { - self.wr_tagged_u64( - tag_mod_child, - def_to_u64(tcx.map.local_def_id(foreign_item.id))); - } + self.start_tag(tag_mod_children); + self.seq(&fm.items, |_, foreign_item| { + tcx.map.local_def_id(foreign_item.id) + }); + <[def::Export]>::encode(&[], self).unwrap(); + self.end_tag(); + self.encode_visibility(vis); encode_stability(self, stab); encode_deprecation(self, depr); } hir::ItemTy(..) => { encode_def_id_and_key(self, def_id); - encode_family(self, 'y'); + encode_family(self, Family::Type); self.encode_bounds_and_type_for_item(def_id); encode_name(self, item.name); self.encode_visibility(vis); @@ -966,15 +879,19 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { } hir::ItemEnum(ref enum_definition, _) => { encode_def_id_and_key(self, def_id); - encode_family(self, 't'); + encode_family(self, Family::Enum); encode_item_variances(self, item.id); self.encode_bounds_and_type_for_item(def_id); encode_name(self, item.name); encode_attributes(self, &item.attrs); self.encode_repr_attrs(&item.attrs); - for v in &enum_definition.variants { - encode_variant_id(self, tcx.map.local_def_id(v.node.data.id())); - } + + self.start_tag(tag_mod_children); + self.seq(&enum_definition.variants, |_, v| { + tcx.map.local_def_id(v.node.data.id()) + }); + <[def::Export]>::encode(&[], self).unwrap(); + self.end_tag(); // Encode inherent implementations for self enumeration. encode_inherent_implementations(self, def_id); @@ -990,11 +907,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { /* Now, make an item for the class itself */ encode_def_id_and_key(self, def_id); - encode_family(self, match *struct_def { - hir::VariantData::Struct(..) => 'S', - hir::VariantData::Tuple(..) => 's', - hir::VariantData::Unit(..) => 'u', - }); + encode_family(self, Family::Struct(variant.kind)); self.encode_bounds_and_type_for_item(def_id); encode_item_variances(self, item.id); @@ -1008,15 +921,16 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - self.encode_struct_fields(variant); + self.encode_variant_fields(variant); // Encode inherent implementations for self structure. encode_inherent_implementations(self, def_id); if !struct_def.is_struct() { let ctor_did = tcx.map.local_def_id(struct_def.id()); - self.wr_tagged_u64(tag_items_data_item_struct_ctor, - def_to_u64(ctor_did)); + self.start_tag(tag_items_data_item_struct_ctor); + ctor_did.encode(self).unwrap(); + self.end_tag(); } } hir::ItemUnion(..) => { @@ -1024,7 +938,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { let variant = def.struct_variant(); encode_def_id_and_key(self, def_id); - encode_family(self, 'U'); + encode_family(self, Family::Union); self.encode_bounds_and_type_for_item(def_id); encode_item_variances(self, item.id); @@ -1038,7 +952,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - self.encode_struct_fields(variant); + self.encode_variant_fields(variant); encode_inlined_item(self, InlinedItemRef::Item(def_id, item)); self.encode_mir(def_id); @@ -1046,28 +960,24 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { // Encode inherent implementations for self union. encode_inherent_implementations(self, def_id); } - hir::ItemDefaultImpl(unsafety, _) => { + hir::ItemDefaultImpl(..) => { encode_def_id_and_key(self, def_id); - encode_family(self, 'd'); + encode_family(self, Family::DefaultImpl); encode_name(self, item.name); - encode_unsafety(self, unsafety); let trait_ref = tcx.impl_trait_ref(tcx.map.local_def_id(item.id)).unwrap(); encode_trait_ref(self, trait_ref, tag_item_trait_ref); } - hir::ItemImpl(unsafety, polarity, ..) => { - // We need to encode information about the default methods we - // have inherited, so we drive self based on the impl structure. - let impl_items = tcx.impl_items.borrow(); - let items = &impl_items[&def_id]; - + hir::ItemImpl(_, polarity, ..) => { encode_def_id_and_key(self, def_id); - encode_family(self, 'i'); + encode_family(self, Family::Impl); self.encode_bounds_and_type_for_item(def_id); encode_name(self, item.name); encode_attributes(self, &item.attrs); - encode_unsafety(self, unsafety); - encode_polarity(self, polarity); + + self.start_tag(tag_polarity); + polarity.encode(self).unwrap(); + self.end_tag(); match tcx.custom_coerce_unsized_kinds @@ -1076,30 +986,17 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { { Some(&kind) => { self.start_tag(tag_impl_coerce_unsized_kind); - kind.encode(self.ecx); + kind.encode(self); self.end_tag(); } None => {} } - for &item_def_id in items { - self.start_tag(tag_item_impl_item); - match item_def_id { - ty::ConstTraitItemId(item_def_id) => { - encode_def_id(self, item_def_id); - encode_item_sort(self, 'C'); - } - ty::MethodTraitItemId(item_def_id) => { - encode_def_id(self, item_def_id); - encode_item_sort(self, 'r'); - } - ty::TypeTraitItemId(item_def_id) => { - encode_def_id(self, item_def_id); - encode_item_sort(self, 't'); - } - } - self.end_tag(); - } + self.start_tag(tag_mod_children); + let items = tcx.impl_or_trait_items(def_id); + self.seq(&items[..], |_, id| id.def_id()); + <[def::Export]>::encode(&[], self).unwrap(); + self.end_tag(); let did = tcx.map.local_def_id(item.id); if let Some(trait_ref) = tcx.impl_trait_ref(did) { @@ -1114,20 +1011,34 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { Some(parent), _ => None, }); - encode_parent_impl(self, parent); + parent.map(|parent| { + self.start_tag(tag_items_data_parent_impl); + parent.encode(self).unwrap(); + self.end_tag(); + }); } encode_stability(self, stab); encode_deprecation(self, depr); } hir::ItemTrait(..) => { encode_def_id_and_key(self, def_id); - encode_family(self, 'I'); + encode_family(self, Family::Trait); encode_item_variances(self, item.id); let trait_def = tcx.lookup_trait_def(def_id); let trait_predicates = tcx.lookup_predicates(def_id); - encode_unsafety(self, trait_def.unsafety); - encode_paren_sugar(self, trait_def.paren_sugar); - encode_defaulted(self, tcx.trait_has_default_impl(def_id)); + + self.start_tag(tag_unsafety); + trait_def.unsafety.encode(self).unwrap(); + self.end_tag(); + + self.start_tag(tag_paren_sugar); + trait_def.paren_sugar.encode(self).unwrap(); + self.end_tag(); + + self.start_tag(tag_defaulted_trait); + tcx.trait_has_default_impl(def_id).encode(self).unwrap(); + self.end_tag(); + encode_associated_type_names(self, &trait_def.associated_type_names); self.encode_generics(&trait_def.generics, &trait_predicates); self.encode_predicates(&tcx.lookup_super_predicates(def_id), @@ -1138,27 +1049,12 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { self.encode_visibility(vis); encode_stability(self, stab); encode_deprecation(self, depr); - for &method_def_id in tcx.trait_item_def_ids(def_id).iter() { - self.start_tag(tag_item_trait_item); - match method_def_id { - ty::ConstTraitItemId(const_def_id) => { - encode_def_id(self, const_def_id); - encode_item_sort(self, 'C'); - } - ty::MethodTraitItemId(method_def_id) => { - encode_def_id(self, method_def_id); - encode_item_sort(self, 'r'); - } - ty::TypeTraitItemId(type_def_id) => { - encode_def_id(self, type_def_id); - encode_item_sort(self, 't'); - } - } - self.end_tag(); - self.wr_tagged_u64(tag_mod_child, - def_to_u64(method_def_id.def_id())); - } + self.start_tag(tag_mod_children); + let items = tcx.impl_or_trait_items(def_id); + self.seq(&items[..], |_, id| id.def_id()); + <[def::Export]>::encode(&[], self).unwrap(); + self.end_tag(); // Encode inherent implementations for self trait. encode_inherent_implementations(self, def_id); @@ -1227,7 +1123,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { // Foo()` and `struct Foo` let ctor_def_id = self.tcx.map.local_def_id(struct_node_id); self.record(ctor_def_id, - ItemContentBuilder::encode_struct_ctor, + EncodeContext::encode_struct_ctor, (def_id, item.id, struct_node_id)); } } @@ -1241,8 +1137,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { def_id: DefId, impl_id: ast::NodeId, ast_items: &[hir::ImplItem]) { - let impl_items = self.tcx.impl_items.borrow(); - let items = &impl_items[&def_id]; + let items = self.tcx.impl_or_trait_items(def_id); // Iterate down the trait items, emitting them. We rely on the // assumption that all of the actually implemented trait items @@ -1258,7 +1153,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { let trait_item_def_id = trait_item_def_id.def_id(); self.record(trait_item_def_id, - ItemContentBuilder::encode_info_for_impl_item, + EncodeContext::encode_info_for_impl_item, (impl_id, trait_item_def_id, ast_item)); } } @@ -1267,19 +1162,18 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { def_id: DefId, trait_items: &[hir::TraitItem]) { // Now output the trait item info for each trait item. - let tcx = self.tcx; - let r = tcx.trait_item_def_ids(def_id); + let r = self.tcx.impl_or_trait_items(def_id); for (item_def_id, trait_item) in r.iter().zip(trait_items) { let item_def_id = item_def_id.def_id(); assert!(item_def_id.is_local()); self.record(item_def_id, - ItemContentBuilder::encode_info_for_trait_item, + EncodeContext::encode_info_for_trait_item, (def_id, item_def_id, trait_item)); } } } -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_foreign_item(&mut self, (def_id, nitem): (DefId, &hir::ForeignItem)) { let tcx = self.tcx; @@ -1292,7 +1186,7 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { self.encode_visibility(&nitem.vis); match nitem.node { hir::ForeignItemFn(ref fndecl, _) => { - encode_family(self, FN_FAMILY); + encode_family(self, Family::Fn); self.encode_bounds_and_type_for_item(def_id); encode_name(self, nitem.name); encode_attributes(self, &nitem.attrs); @@ -1303,11 +1197,11 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { self.encode_method_argument_names(&fndecl); } hir::ForeignItemStatic(_, mutbl) => { - if mutbl { - encode_family(self, 'b'); + encode_family(self, if mutbl { + Family::MutStatic } else { - encode_family(self, 'c'); - } + Family::ImmStatic + }); self.encode_bounds_and_type_for_item(def_id); encode_attributes(self, &nitem.attrs); let stab = tcx.lookup_stability(tcx.map.local_def_id(nitem.id)); @@ -1335,7 +1229,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { match item.node { hir::ItemExternCrate(_) | hir::ItemUse(_) => (), // ignore these _ => self.index.record(def_id, - ItemContentBuilder::encode_info_for_item, + EncodeContext::encode_info_for_item, (def_id, item)), } self.index.encode_addl_info_for_item(item); @@ -1344,7 +1238,7 @@ impl<'a, 'b, 'tcx> Visitor<'tcx> for EncodeVisitor<'a, 'b, 'tcx> { intravisit::walk_foreign_item(self, ni); let def_id = self.index.tcx.map.local_def_id(ni.id); self.index.record(def_id, - ItemContentBuilder::encode_info_for_foreign_item, + EncodeContext::encode_info_for_foreign_item, (def_id, ni)); } fn visit_ty(&mut self, ty: &'tcx hir::Ty) { @@ -1358,7 +1252,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { if let hir::TyImplTrait(_) = ty.node { let def_id = self.tcx.map.local_def_id(ty.id); self.record(def_id, - ItemContentBuilder::encode_info_for_anon_ty, + EncodeContext::encode_info_for_anon_ty, def_id); } } @@ -1368,7 +1262,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { hir::ExprClosure(..) => { let def_id = self.tcx.map.local_def_id(expr.id); self.record(def_id, - ItemContentBuilder::encode_info_for_closure, + EncodeContext::encode_info_for_closure, def_id); } _ => { } @@ -1376,10 +1270,9 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { } } -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { +impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_anon_ty(&mut self, def_id: DefId) { encode_def_id_and_key(self, def_id); - encode_family(self, 'y'); self.encode_bounds_and_type_for_item(def_id); } @@ -1389,11 +1282,11 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { encode_name(self, syntax::parse::token::intern("")); self.start_tag(tag_items_closure_ty); - tcx.tables.borrow().closure_tys[&def_id].encode(self.ecx).unwrap(); + tcx.tables.borrow().closure_tys[&def_id].encode(self).unwrap(); self.end_tag(); self.start_tag(tag_items_closure_kind); - tcx.closure_kind(def_id).encode(self.ecx).unwrap(); + tcx.closure_kind(def_id).encode(self).unwrap(); self.end_tag(); assert!(self.mir_map.map.contains_key(&def_id)); @@ -1401,30 +1294,29 @@ impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { } } -fn encode_info_for_items<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>) - -> (IndexData, FnvHashMap, u32>) { +fn encode_info_for_items(ecx: &mut EncodeContext) -> IndexData { let krate = ecx.tcx.map.krate(); ecx.start_tag(tag_items_data); - let fields = { + let items = { let mut index = IndexBuilder::new(ecx); index.record(DefId::local(CRATE_DEF_INDEX), - ItemContentBuilder::encode_info_for_mod, + EncodeContext::encode_info_for_mod, FromId(CRATE_NODE_ID, (&krate.module, - &[], + &krate.attrs, syntax::parse::token::intern(&ecx.link_meta.crate_name), &hir::Public))); let mut visitor = EncodeVisitor { index: index, }; krate.visit_all_items(&mut visitor); - visitor.index.into_fields() + visitor.index.into_items() }; ecx.end_tag(); - fields + items } fn encode_item_index(ecx: &mut EncodeContext, index: IndexData) { @@ -1439,40 +1331,12 @@ fn encode_attributes(ecx: &mut EncodeContext, attrs: &[ast::Attribute]) { ecx.end_tag(); } -fn encode_unsafety(ecx: &mut EncodeContext, unsafety: hir::Unsafety) { - let byte: u8 = match unsafety { - hir::Unsafety::Normal => 0, - hir::Unsafety::Unsafe => 1, - }; - ecx.wr_tagged_u8(tag_unsafety, byte); -} - -fn encode_paren_sugar(ecx: &mut EncodeContext, paren_sugar: bool) { - let byte: u8 = if paren_sugar {1} else {0}; - ecx.wr_tagged_u8(tag_paren_sugar, byte); -} - -fn encode_defaulted(ecx: &mut EncodeContext, is_defaulted: bool) { - let byte: u8 = if is_defaulted {1} else {0}; - ecx.wr_tagged_u8(tag_defaulted_trait, byte); -} - fn encode_associated_type_names(ecx: &mut EncodeContext, names: &[Name]) { ecx.start_tag(tag_associated_type_names); - for &name in names { - ecx.wr_tagged_str(tag_associated_type_name, &name.as_str()); - } + names.encode(ecx).unwrap(); ecx.end_tag(); } -fn encode_polarity(ecx: &mut EncodeContext, polarity: hir::ImplPolarity) { - let byte: u8 = match polarity { - hir::ImplPolarity::Positive => 0, - hir::ImplPolarity::Negative => 1, - }; - ecx.wr_tagged_u8(tag_polarity, byte); -} - fn encode_crate_deps(ecx: &mut EncodeContext, cstore: &cstore::CStore) { fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<(CrateNum, Rc)> { @@ -1500,48 +1364,56 @@ fn encode_crate_deps(ecx: &mut EncodeContext, cstore: &cstore::CStore) { // FIXME (#2166): This is not nearly enough to support correct versioning // but is enough to get transitive crate dependencies working. ecx.start_tag(tag_crate_deps); - for (_cnum, dep) in get_ordered_deps(cstore) { - encode_crate_dep(ecx, &dep); - } + ecx.seq(&get_ordered_deps(cstore), |_, &(_, ref dep)| { + (dep.name(), decoder::get_crate_hash(dep.data()), + dep.explicitly_linked.get()) + }); ecx.end_tag(); } fn encode_lang_items(ecx: &mut EncodeContext) { - ecx.start_tag(tag_lang_items); - - for (i, &opt_def_id) in ecx.tcx.lang_items.items().iter().enumerate() { - if let Some(def_id) = opt_def_id { - if def_id.is_local() { - ecx.start_tag(tag_lang_items_item); - ecx.wr_tagged_u32(tag_lang_items_item_id, i as u32); - ecx.wr_tagged_u32(tag_lang_items_item_index, def_id.index.as_u32()); - ecx.end_tag(); + let tcx = ecx.tcx; + let lang_items = || { + tcx.lang_items.items().iter().enumerate().filter_map(|(i, &opt_def_id)| { + if let Some(def_id) = opt_def_id { + if def_id.is_local() { + return Some((def_id.index, i)); + } } - } - } + None + }) + }; - for i in &ecx.tcx.lang_items.missing { - ecx.wr_tagged_u32(tag_lang_items_missing, *i as u32); - } + let count = lang_items().count(); + let mut lang_items = lang_items(); - ecx.end_tag(); // tag_lang_items + ecx.start_tag(tag_lang_items); + ecx.seq(0..count, |_, _| lang_items.next().unwrap()); + ecx.end_tag(); + + ecx.start_tag(tag_lang_items_missing); + tcx.lang_items.missing.encode(ecx).unwrap(); + ecx.end_tag(); } fn encode_native_libraries(ecx: &mut EncodeContext) { - ecx.start_tag(tag_native_libraries); - - for &(ref lib, kind) in ecx.tcx.sess.cstore.used_libraries().iter() { - match kind { - cstore::NativeStatic => {} // these libraries are not propagated - cstore::NativeFramework | cstore::NativeUnknown => { - ecx.start_tag(tag_native_libraries_lib); - ecx.wr_tagged_u32(tag_native_libraries_kind, kind as u32); - ecx.wr_tagged_str(tag_native_libraries_name, lib); - ecx.end_tag(); + let used_libraries = ecx.tcx.sess.cstore.used_libraries(); + let libs = || { + used_libraries.iter().filter_map(|&(ref lib, kind)| { + match kind { + cstore::NativeStatic => None, // these libraries are not propagated + cstore::NativeFramework | cstore::NativeUnknown => { + Some((kind, lib)) + } } - } - } + }) + }; + let count = libs().count(); + let mut libs = libs(); + + ecx.start_tag(tag_native_libraries); + ecx.seq(0..count, |_, _| libs.next().unwrap()); ecx.end_tag(); } @@ -1549,84 +1421,55 @@ fn encode_plugin_registrar_fn(ecx: &mut EncodeContext) { match ecx.tcx.sess.plugin_registrar_fn.get() { Some(id) => { let def_id = ecx.tcx.map.local_def_id(id); - ecx.wr_tagged_u32(tag_plugin_registrar_fn, def_id.index.as_u32()); + ecx.start_tag(tag_plugin_registrar_fn); + def_id.index.encode(ecx).unwrap(); + ecx.end_tag(); } None => {} } } fn encode_codemap(ecx: &mut EncodeContext) { - ecx.start_tag(tag_codemap); let codemap = ecx.tcx.sess.codemap(); + let all_filemaps = codemap.files.borrow(); + let filemaps = || { + // No need to export empty filemaps, as they can't contain spans + // that need translation. + // Also no need to re-export imported filemaps, as any downstream + // crate will import them from their original source. + all_filemaps.iter().filter(|filemap| { + !filemap.lines.borrow().is_empty() && !filemap.is_imported() + }) + }; - for filemap in &codemap.files.borrow()[..] { - - if filemap.lines.borrow().is_empty() || filemap.is_imported() { - // No need to export empty filemaps, as they can't contain spans - // that need translation. - // Also no need to re-export imported filemaps, as any downstream - // crate will import them from their original source. - continue; - } - - ecx.start_tag(tag_codemap_filemap); - filemap.encode(ecx).unwrap(); - ecx.end_tag(); - } + let count = filemaps().count(); + let mut filemaps = filemaps(); + ecx.start_tag(tag_codemap); + ecx.seq(0..count, |_, _| filemaps.next().unwrap()); ecx.end_tag(); } /// Serialize the text of the exported macros -fn encode_macro_defs(ecx: &mut EncodeContext, - krate: &hir::Crate) { +fn encode_macro_defs(ecx: &mut EncodeContext) { + let tcx = ecx.tcx; ecx.start_tag(tag_macro_defs); - for def in &krate.exported_macros { - ecx.start_tag(tag_macro_def); - - encode_name(ecx, def.name); - encode_attributes(ecx, &def.attrs); - let &BytePos(lo) = &def.span.lo; - let &BytePos(hi) = &def.span.hi; - ecx.wr_tagged_u32(tag_macro_def_span_lo, lo); - ecx.wr_tagged_u32(tag_macro_def_span_hi, hi); - - ecx.wr_tagged_str(tag_macro_def_body, - &::syntax::print::pprust::tts_to_string(&def.body)); - - ecx.end_tag(); - } + ecx.seq(&tcx.map.krate().exported_macros, |_, def| { + let body = ::syntax::print::pprust::tts_to_string(&def.body); + (def.name, &def.attrs, def.span, body) + }); ecx.end_tag(); if ecx.tcx.sess.crate_types.borrow().contains(&CrateTypeRustcMacro) { let id = ecx.tcx.sess.derive_registrar_fn.get().unwrap(); let did = ecx.tcx.map.local_def_id(id); - ecx.wr_tagged_u32(tag_macro_derive_registrar, did.index.as_u32()); + + ecx.start_tag(tag_macro_derive_registrar); + did.index.encode(ecx).unwrap(); + ecx.end_tag(); } } -fn encode_struct_field_attrs(ecx: &mut EncodeContext, krate: &hir::Crate) { - struct StructFieldVisitor<'a, 'b:'a, 'tcx:'b> { - ecx: &'a mut EncodeContext<'b, 'tcx> - } - - impl<'a, 'b, 'tcx, 'v> Visitor<'v> for StructFieldVisitor<'a, 'b, 'tcx> { - fn visit_struct_field(&mut self, field: &hir::StructField) { - self.ecx.start_tag(tag_struct_field); - let def_id = self.ecx.tcx.map.local_def_id(field.id); - encode_def_id(self.ecx, def_id); - encode_attributes(self.ecx, &field.attrs); - self.ecx.end_tag(); - } - } - - ecx.start_tag(tag_struct_fields); - krate.visit_all_items(&mut StructFieldVisitor { ecx: ecx }); - ecx.end_tag(); -} - - - struct ImplVisitor<'a, 'tcx:'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, impls: FnvHashMap> @@ -1646,20 +1489,19 @@ impl<'a, 'tcx, 'v> Visitor<'v> for ImplVisitor<'a, 'tcx> { } /// Encodes an index, mapping each trait to its (local) implementations. -fn encode_impls(ecx: &mut EncodeContext, krate: &hir::Crate) { +fn encode_impls(ecx: &mut EncodeContext) { let mut visitor = ImplVisitor { tcx: ecx.tcx, impls: FnvHashMap() }; - krate.visit_all_items(&mut visitor); + ecx.tcx.map.krate().visit_all_items(&mut visitor); ecx.start_tag(tag_impls); - for (trait_, trait_impls) in visitor.impls { - ecx.start_tag(tag_impls_trait); - encode_def_id(ecx, trait_); - for impl_ in trait_impls { - ecx.wr_tagged_u64(tag_impls_trait_impl, def_to_u64(impl_)); - } + for (trait_def_id, trait_impls) in visitor.impls { + // FIXME(eddyb) Avoid wrapping the entries in docs. + ecx.start_tag(0); + (trait_def_id.krate.as_u32(), trait_def_id.index).encode(ecx).unwrap(); + trait_impls.encode(ecx).unwrap(); ecx.end_tag(); } ecx.end_tag(); @@ -1673,74 +1515,32 @@ fn encode_impls(ecx: &mut EncodeContext, krate: &hir::Crate) { // definition (as that's not defined in this crate). fn encode_reachable(ecx: &mut EncodeContext) { ecx.start_tag(tag_reachable_ids); - for &id in ecx.reachable { - let def_id = ecx.tcx.map.local_def_id(id); - ecx.wr_tagged_u32(tag_reachable_id, def_id.index.as_u32()); - } + + let reachable = ecx.reachable; + ecx.seq(reachable, |ecx, &id| ecx.tcx.map.local_def_id(id).index); + ecx.end_tag(); } -fn encode_crate_dep(ecx: &mut EncodeContext, - dep: &cstore::CrateMetadata) { - ecx.start_tag(tag_crate_dep); - ecx.wr_tagged_str(tag_crate_dep_crate_name, &dep.name()); - let hash = decoder::get_crate_hash(dep.data()); - ecx.wr_tagged_u64(tag_crate_dep_hash, hash.as_u64()); - ecx.wr_tagged_u8(tag_crate_dep_explicitly_linked, - dep.explicitly_linked.get() as u8); - ecx.end_tag(); -} - -fn encode_hash(ecx: &mut EncodeContext, hash: &Svh) { - ecx.wr_tagged_u64(tag_crate_hash, hash.as_u64()); -} - -fn encode_rustc_version(ecx: &mut EncodeContext) { - ecx.wr_tagged_str(tag_rustc_version, &rustc_version()); -} - -fn encode_crate_name(ecx: &mut EncodeContext, crate_name: &str) { - ecx.wr_tagged_str(tag_crate_crate_name, crate_name); -} - -fn encode_crate_disambiguator(ecx: &mut EncodeContext, crate_disambiguator: &str) { - ecx.wr_tagged_str(tag_crate_disambiguator, crate_disambiguator); -} - -fn encode_crate_triple(ecx: &mut EncodeContext, triple: &str) { - ecx.wr_tagged_str(tag_crate_triple, triple); -} - fn encode_dylib_dependency_formats(ecx: &mut EncodeContext) { - let tag = tag_dylib_dependency_formats; + ecx.start_tag(tag_dylib_dependency_formats); match ecx.tcx.sess.dependency_formats.borrow().get(&config::CrateTypeDylib) { Some(arr) => { - let s = arr.iter().enumerate().filter_map(|(i, slot)| { - let kind = match *slot { + ecx.seq(arr, |_, slot| { + match *slot { Linkage::NotLinked | - Linkage::IncludedFromDylib => return None, - Linkage::Dynamic => "d", - Linkage::Static => "s", - }; - Some(format!("{}:{}", i + 1, kind)) - }).collect::>(); - ecx.wr_tagged_str(tag, &s.join(",")); + Linkage::IncludedFromDylib => None, + + Linkage::Dynamic => Some(LinkagePreference::RequireDynamic), + Linkage::Static => Some(LinkagePreference::RequireStatic), + } + }); } None => { - ecx.wr_tagged_str(tag, ""); - } - } -} - -fn encode_panic_strategy(ecx: &mut EncodeContext) { - match ecx.tcx.sess.opts.cg.panic { - PanicStrategy::Unwind => { - ecx.wr_tagged_u8(tag_panic_strategy, b'U'); - } - PanicStrategy::Abort => { - ecx.wr_tagged_u8(tag_panic_strategy, b'A'); + <[Option]>::encode(&[], ecx).unwrap(); } } + ecx.end_tag(); } pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1764,6 +1564,7 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, reachable: reachable, mir_map: mir_map, type_shorthands: Default::default(), + xrefs: Default::default() }); // RBML compacts the encoded bytes whenever appropriate, @@ -1806,24 +1607,34 @@ pub fn encode_metadata<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } fn encode_metadata_inner(ecx: &mut EncodeContext) { - encode_rustc_version(ecx); + ecx.wr_tagged_str(tag_rustc_version, &rustc_version()); let tcx = ecx.tcx; let link_meta = ecx.link_meta; - encode_crate_name(ecx, &link_meta.crate_name); - encode_crate_triple(ecx, &tcx.sess.opts.target_triple); - encode_hash(ecx, &link_meta.crate_hash); - encode_crate_disambiguator(ecx, &tcx.sess.local_crate_disambiguator()); - encode_dylib_dependency_formats(ecx); - encode_panic_strategy(ecx); - let krate = tcx.map.krate(); + ecx.start_tag(tag_crate_crate_name); + link_meta.crate_name.encode(ecx).unwrap(); + ecx.end_tag(); + + ecx.start_tag(tag_crate_triple); + tcx.sess.opts.target_triple.encode(ecx).unwrap(); + ecx.end_tag(); + + ecx.start_tag(tag_crate_hash); + link_meta.crate_hash.encode(ecx).unwrap(); + ecx.end_tag(); + + ecx.start_tag(tag_crate_disambiguator); + tcx.sess.local_crate_disambiguator().encode(ecx).unwrap(); + ecx.end_tag(); + + encode_dylib_dependency_formats(ecx); + + ecx.start_tag(tag_panic_strategy); + ecx.tcx.sess.opts.cg.panic.encode(ecx); + ecx.end_tag(); let mut i = ecx.position(); - encode_attributes(ecx, &krate.attrs); - let attr_bytes = ecx.position() - i; - - i = ecx.position(); encode_crate_deps(ecx, ecx.cstore); let dep_bytes = ecx.position() - i; @@ -1849,12 +1660,12 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) { // Encode macro definitions i = ecx.position(); - encode_macro_defs(ecx, krate); + encode_macro_defs(ecx); let macro_defs_bytes = ecx.position() - i; // Encode the def IDs of impls, for coherence checking. i = ecx.position(); - encode_impls(ecx, krate); + encode_impls(ecx); let impl_bytes = ecx.position() - i; // Encode reachability info. @@ -1865,7 +1676,7 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) { // Encode and index the items. ecx.start_tag(tag_items); i = ecx.position(); - let (items, xrefs) = encode_info_for_items(ecx); + let items = encode_info_for_items(ecx); let item_bytes = ecx.position() - i; ecx.end_tag(); @@ -1874,11 +1685,9 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) { let index_bytes = ecx.position() - i; i = ecx.position(); - encode_xrefs(ecx, xrefs); + ecx.encode_xrefs(); let xref_bytes = ecx.position() - i; - encode_struct_field_attrs(ecx, krate); - let total_bytes = ecx.position(); if ecx.tcx.sess.meta_stats() { @@ -1890,7 +1699,6 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) { } println!("metadata stats:"); - println!(" attribute bytes: {}", attr_bytes); println!(" dep bytes: {}", dep_bytes); println!(" lang item bytes: {}", lang_item_bytes); println!(" native bytes: {}", native_lib_bytes); diff --git a/src/librustc_metadata/index_builder.rs b/src/librustc_metadata/index_builder.rs index fd25128575f..2cfa6f8d5d1 100644 --- a/src/librustc_metadata/index_builder.rs +++ b/src/librustc_metadata/index_builder.rs @@ -38,17 +38,11 @@ //! //! What record will do is to (a) record the current offset, (b) emit //! the `common::data_item` tag, and then call `callback_fn` with the -//! given data as well as an `ItemContentBuilder`. Once `callback_fn` +//! given data as well as the `EncodingContext`. Once `callback_fn` //! returns, the `common::data_item` tag will be closed. //! -//! The `ItemContentBuilder` is another type that just offers access -//! to the `ecx` that was given in, as well as maintaining a list of -//! `xref` instances, which are used to extract common data so it is -//! not re-serialized. -//! -//! `ItemContentBuilder` is a distinct type which does not offer the -//! `record` method, so that we can ensure that `common::data_item` elements -//! are never nested. +//! `EncodingContext` does not offer the `record` method, so that we +//! can ensure that `common::data_item` elements are never nested. //! //! In addition, while the `callback_fn` is executing, we will push a //! task `MetaData(some_def_id)`, which can then observe the @@ -67,8 +61,7 @@ use index::IndexData; use rustc::dep_graph::DepNode; use rustc::hir; use rustc::hir::def_id::DefId; -use rustc::ty::{self, TyCtxt}; -use rustc_data_structures::fnv::FnvHashMap; +use rustc::ty::TyCtxt; use syntax::ast; use std::ops::{Deref, DerefMut}; @@ -77,54 +70,27 @@ use std::ops::{Deref, DerefMut}; /// Item encoding cannot be nested. pub struct IndexBuilder<'a, 'b: 'a, 'tcx: 'b> { items: IndexData, - builder: ItemContentBuilder<'a, 'b, 'tcx>, -} - -/// Builder that can encode the content of items, but can't start a -/// new item itself. Most code is attached to here. -pub struct ItemContentBuilder<'a, 'b: 'a, 'tcx: 'b> { - xrefs: FnvHashMap, u32>, // sequentially-assigned pub ecx: &'a mut EncodeContext<'b, 'tcx>, } impl<'a, 'b, 'tcx> Deref for IndexBuilder<'a, 'b, 'tcx> { type Target = EncodeContext<'b, 'tcx>; fn deref(&self) -> &Self::Target { - self.builder.ecx + self.ecx } } impl<'a, 'b, 'tcx> DerefMut for IndexBuilder<'a, 'b, 'tcx> { fn deref_mut(&mut self) -> &mut Self::Target { - self.builder.ecx - } -} - -impl<'a, 'b, 'tcx> Deref for ItemContentBuilder<'a, 'b, 'tcx> { - type Target = EncodeContext<'b, 'tcx>; - fn deref(&self) -> &Self::Target { self.ecx } } -impl<'a, 'b, 'tcx> DerefMut for ItemContentBuilder<'a, 'b, 'tcx> { - fn deref_mut(&mut self) -> &mut Self::Target { - self.ecx - } -} - -/// "interned" entries referenced by id -#[derive(PartialEq, Eq, Hash)] -pub enum XRef<'tcx> { Predicate(ty::Predicate<'tcx>) } - impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { pub fn new(ecx: &'a mut EncodeContext<'b, 'tcx>) -> Self { IndexBuilder { items: IndexData::new(ecx.tcx.map.num_local_def_ids()), - builder: ItemContentBuilder { - ecx: ecx, - xrefs: FnvHashMap(), - }, + ecx: ecx, } } @@ -147,28 +113,21 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { /// content system. pub fn record(&mut self, id: DefId, - op: fn(&mut ItemContentBuilder<'a, 'b, 'tcx>, DATA), + op: fn(&mut EncodeContext<'b, 'tcx>, DATA), data: DATA) where DATA: DepGraphRead { - let position = self.builder.ecx.mark_stable_position(); + let position = self.ecx.mark_stable_position(); self.items.record(id, position); let _task = self.tcx.dep_graph.in_task(DepNode::MetaData(id)); - self.builder.ecx.start_tag(tag_items_data_item).unwrap(); + self.ecx.start_tag(tag_items_data_item).unwrap(); data.read(self.tcx); - op(&mut self.builder, data); - self.builder.ecx.end_tag().unwrap(); + op(&mut self.ecx, data); + self.ecx.end_tag().unwrap(); } - pub fn into_fields(self) -> (IndexData, FnvHashMap, u32>) { - (self.items, self.builder.xrefs) - } -} - -impl<'a, 'b, 'tcx> ItemContentBuilder<'a, 'b, 'tcx> { - pub fn add_xref(&mut self, xref: XRef<'tcx>) -> u32 { - let old_len = self.xrefs.len() as u32; - *self.xrefs.entry(xref).or_insert(old_len) + pub fn into_items(self) -> IndexData { + self.items } } diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index e5f7aab38c3..b7125daa4ad 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -17,6 +17,7 @@ html_root_url = "https://doc.rust-lang.org/nightly/")] #![cfg_attr(not(stage0), deny(warnings))] +#![feature(conservative_impl_trait)] #![feature(core_intrinsics)] #![feature(box_patterns)] #![feature(dotdot_in_tuple_patterns)] diff --git a/src/librustc_metadata/rbml/reader.rs b/src/librustc_metadata/rbml/reader.rs index 9bbeb73ce3e..24a0329602b 100644 --- a/src/librustc_metadata/rbml/reader.rs +++ b/src/librustc_metadata/rbml/reader.rs @@ -80,19 +80,16 @@ impl<'doc> Doc<'doc> { } pub fn get(&self, tag: usize) -> Doc<'doc> { - get_doc(*self, tag) + match maybe_get_doc(*self, tag) { + Some(d) => d, + None => { + bug!("failed to find block with tag {:?}", tag); + } + } } - pub fn is_empty(&self) -> bool { - self.start == self.end - } - - pub fn as_str(&self) -> &'doc str { - str::from_utf8(&self.data[self.start..self.end]).unwrap() - } - - pub fn to_string(&self) -> String { - self.as_str().to_string() + pub fn children(self) -> DocsIterator<'doc> { + DocsIterator { d: self } } } @@ -129,7 +126,7 @@ pub struct Res { pub next: usize, } -pub fn tag_at(data: &[u8], start: usize) -> Result { +fn tag_at(data: &[u8], start: usize) -> Result { let v = data[start] as usize; if v < 0xf0 { Ok(Res { @@ -180,7 +177,7 @@ fn vuint_at_slow(data: &[u8], start: usize) -> Result { Err(Error::IntTooBig(a as usize)) } -pub fn vuint_at(data: &[u8], start: usize) -> Result { +fn vuint_at(data: &[u8], start: usize) -> Result { if data.len() - start < 4 { return vuint_at_slow(data, start); } @@ -234,7 +231,7 @@ pub fn vuint_at(data: &[u8], start: usize) -> Result { } } -pub fn tag_len_at(data: &[u8], next: usize) -> Result { +fn tag_len_at(data: &[u8], next: usize) -> Result { vuint_at(data, next) } @@ -255,27 +252,14 @@ pub fn maybe_get_doc<'a>(d: Doc<'a>, tg: usize) -> Option> { None } -pub fn get_doc<'a>(d: Doc<'a>, tg: usize) -> Doc<'a> { - match maybe_get_doc(d, tg) { - Some(d) => d, - None => { - bug!("failed to find block with tag {:?}", tg); - } - } -} - -pub fn docs<'a>(d: Doc<'a>) -> DocsIterator<'a> { - DocsIterator { d: d } -} - pub struct DocsIterator<'a> { d: Doc<'a>, } impl<'a> Iterator for DocsIterator<'a> { - type Item = (usize, Doc<'a>); + type Item = Doc<'a>; - fn next(&mut self) -> Option<(usize, Doc<'a>)> { + fn next(&mut self) -> Option> { if self.d.start >= self.d.end { return None; } @@ -297,98 +281,10 @@ impl<'a> Iterator for DocsIterator<'a> { }; self.d.start = end; - return Some((elt_tag.val, doc)); + return Some(doc); } } -pub fn tagged_docs<'a>(d: Doc<'a>, tag: usize) -> TaggedDocsIterator<'a> { - TaggedDocsIterator { - iter: docs(d), - tag: tag, - } -} - -pub struct TaggedDocsIterator<'a> { - iter: DocsIterator<'a>, - tag: usize, -} - -impl<'a> Iterator for TaggedDocsIterator<'a> { - type Item = Doc<'a>; - - fn next(&mut self) -> Option> { - while let Some((tag, doc)) = self.iter.next() { - if tag == self.tag { - return Some(doc); - } - } - None - } -} - -pub fn with_doc_data(d: Doc, f: F) -> T - where F: FnOnce(&[u8]) -> T -{ - f(&d.data[d.start..d.end]) -} - -pub fn doc_as_u8(d: Doc) -> u8 { - assert_eq!(d.end, d.start + 1); - d.data[d.start] -} - -pub fn doc_as_u64(d: Doc) -> u64 { - if d.end >= 8 { - // For performance, we read 8 big-endian bytes, - // and mask off the junk if there is any. This - // obviously won't work on the first 8 bytes - // of a file - we will fall of the start - // of the page and segfault. - - let mut b = [0; 8]; - b.copy_from_slice(&d.data[d.end - 8..d.end]); - let data = unsafe { (*(b.as_ptr() as *const u64)).to_be() }; - let len = d.end - d.start; - if len < 8 { - data & ((1 << (len * 8)) - 1) - } else { - data - } - } else { - let mut result = 0; - for b in &d.data[d.start..d.end] { - result = (result << 8) + (*b as u64); - } - result - } -} - -#[inline] -pub fn doc_as_u16(d: Doc) -> u16 { - doc_as_u64(d) as u16 -} -#[inline] -pub fn doc_as_u32(d: Doc) -> u32 { - doc_as_u64(d) as u32 -} - -#[inline] -pub fn doc_as_i8(d: Doc) -> i8 { - doc_as_u8(d) as i8 -} -#[inline] -pub fn doc_as_i16(d: Doc) -> i16 { - doc_as_u16(d) as i16 -} -#[inline] -pub fn doc_as_i32(d: Doc) -> i32 { - doc_as_u32(d) as i32 -} -#[inline] -pub fn doc_as_i64(d: Doc) -> i64 { - doc_as_u64(d) as i64 -} - #[test] fn test_vuint_at() { let data = &[ diff --git a/src/librustc_metadata/rbml/writer.rs b/src/librustc_metadata/rbml/writer.rs index 94e9b394f1f..46b63cb1340 100644 --- a/src/librustc_metadata/rbml/writer.rs +++ b/src/librustc_metadata/rbml/writer.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use std::mem; use std::io::prelude::*; use std::io::{self, SeekFrom, Cursor}; @@ -112,50 +111,10 @@ impl<'a> Encoder<'a> { Ok(()) } - pub fn wr_tag(&mut self, tag_id: usize, blk: F) -> EncodeResult - where F: FnOnce() -> EncodeResult - { - self.start_tag(tag_id)?; - blk()?; - self.end_tag() - } - - pub fn wr_tagged_bytes(&mut self, tag_id: usize, b: &[u8]) -> EncodeResult { - write_tag(&mut self.opaque.cursor, tag_id)?; - write_vuint(&mut self.opaque.cursor, b.len())?; - self.opaque.cursor.write_all(b) - } - - pub fn wr_tagged_u64(&mut self, tag_id: usize, v: u64) -> EncodeResult { - let bytes: [u8; 8] = unsafe { mem::transmute(v.to_be()) }; - // tagged integers are emitted in big-endian, with no - // leading zeros. - let leading_zero_bytes = v.leading_zeros() / 8; - self.wr_tagged_bytes(tag_id, &bytes[leading_zero_bytes as usize..]) - } - - #[inline] - pub fn wr_tagged_u32(&mut self, tag_id: usize, v: u32) -> EncodeResult { - self.wr_tagged_u64(tag_id, v as u64) - } - - #[inline] - pub fn wr_tagged_u8(&mut self, tag_id: usize, v: u8) -> EncodeResult { - self.wr_tagged_bytes(tag_id, &[v]) - } - pub fn wr_tagged_str(&mut self, tag_id: usize, v: &str) -> EncodeResult { - self.wr_tagged_bytes(tag_id, v.as_bytes()) - } - - pub fn wr_bytes(&mut self, b: &[u8]) -> EncodeResult { - debug!("Write {:?} bytes", b.len()); - self.opaque.cursor.write_all(b) - } - - pub fn wr_str(&mut self, s: &str) -> EncodeResult { - debug!("Write str: {:?}", s); - self.opaque.cursor.write_all(s.as_bytes()) + write_tag(&mut self.opaque.cursor, tag_id)?; + write_vuint(&mut self.opaque.cursor, v.len())?; + self.opaque.cursor.write_all(v.as_bytes()) } pub fn position(&mut self) -> usize { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 83f03e7cfc5..3df3a2decba 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -21,10 +21,10 @@ use ParentLink::{ModuleParentLink, BlockParentLink}; use Resolver; use {resolve_error, resolve_struct_error, ResolutionError}; -use rustc::middle::cstore::{ChildItem, DlDef}; +use rustc::middle::cstore::ChildItem; use rustc::hir::def::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; -use rustc::ty::{self, VariantKind}; +use rustc::ty; use std::cell::Cell; @@ -201,7 +201,7 @@ impl<'b> Resolver<'b> { let module = self.new_extern_crate_module(parent_link, def, item.id); self.define(parent, name, TypeNS, (module, sp, vis)); - self.build_reduced_graph_for_external_crate(module); + self.populate_module_if_necessary(module); } } @@ -388,13 +388,8 @@ impl<'b> Resolver<'b> { } /// Builds the reduced graph for a single item in an external crate. - fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, xcdef: ChildItem) { - let def = match xcdef.def { - DlDef(def) => def, - _ => return, - }; - - if let Def::ForeignMod(def_id) = def { + fn build_reduced_graph_for_external_crate_def(&mut self, parent: Module<'b>, child: ChildItem) { + if let Def::ForeignMod(def_id) = child.def { // Foreign modules have no names. Recur and populate eagerly. for child in self.session.cstore.item_children(def_id) { self.build_reduced_graph_for_external_crate_def(parent, child); @@ -402,8 +397,9 @@ impl<'b> Resolver<'b> { return; } - let name = xcdef.name; - let vis = if parent.is_trait() { ty::Visibility::Public } else { xcdef.vis }; + let def = child.def; + let name = child.name; + let vis = if parent.is_trait() { ty::Visibility::Public } else { child.vis }; match def { Def::Mod(_) | Def::ForeignMod(_) | Def::Enum(..) => { @@ -413,16 +409,12 @@ impl<'b> Resolver<'b> { let module = self.new_module(parent_link, Some(def), None); let _ = self.try_define(parent, name, TypeNS, (module, DUMMY_SP, vis)); } - Def::Variant(_, variant_id) => { + Def::Variant(..) => { debug!("(building reduced graph for external crate) building variant {}", name); // Variants are always treated as importable to allow them to be glob used. // All variants are defined in both type and value namespaces as future-proofing. let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis)); let _ = self.try_define(parent, name, ValueNS, (def, DUMMY_SP, vis)); - if self.session.cstore.variant_kind(variant_id) == Some(VariantKind::Struct) { - // Not adding fields for variants as they are not accessed with a self receiver - self.structs.insert(variant_id, Vec::new()); - } } Def::Fn(..) | Def::Static(..) | @@ -439,7 +431,7 @@ impl<'b> Resolver<'b> { // If this is a trait, add all the trait item names to the trait // info. - let trait_item_def_ids = self.session.cstore.trait_item_def_ids(def_id); + let trait_item_def_ids = self.session.cstore.impl_or_trait_items(def_id); for trait_item_def in &trait_item_def_ids { let trait_item_name = self.session.cstore.item_name(trait_item_def.def_id()); @@ -493,15 +485,6 @@ impl<'b> Resolver<'b> { } } - /// Builds the reduced graph rooted at the 'use' directive for an external - /// crate. - fn build_reduced_graph_for_external_crate(&mut self, root: Module<'b>) { - let root_cnum = root.def_id().unwrap().krate; - for child in self.session.cstore.crate_top_level_items(root_cnum) { - self.build_reduced_graph_for_external_crate_def(root, child); - } - } - /// Ensures that the reduced graph rooted at the given external module /// is built, building it if it is not. pub fn populate_module_if_necessary(&mut self, module: Module<'b>) { diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index 5e78ac7ca94..b03e76c829a 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -1275,6 +1275,7 @@ impl<'a> Resolver<'a> { -> Module<'a> { let mut module = ModuleS::new(parent_link, Some(def), Some(local_node_id)); module.extern_crate_id = Some(local_node_id); + module.populated.set(false); self.arenas.modules.alloc(module) } diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 3764e26b020..186183a8ad4 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -543,10 +543,8 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { .map(|mr| mr.def_id()) } ty::ImplContainer(def_id) => { - let impl_items = self.tcx.impl_items.borrow(); - Some(impl_items.get(&def_id) - .unwrap() - .iter() + let impl_items = self.tcx.impl_or_trait_items(def_id); + Some(impl_items.iter() .find(|mr| { self.tcx.impl_or_trait_item(mr.def_id()).name() == ti.name() diff --git a/src/librustc_trans/collector.rs b/src/librustc_trans/collector.rs index a58de71ca41..b9449eeecf4 100644 --- a/src/librustc_trans/collector.rs +++ b/src/librustc_trans/collector.rs @@ -627,25 +627,23 @@ impl<'a, 'tcx> MirVisitor<'tcx> for MirNeighborCollector<'a, 'tcx> { fn can_result_in_trans_item<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool { - if !match tcx.lookup_item_type(def_id).ty.sty { - ty::TyFnDef(def_id, ..) => { + match tcx.lookup_item_type(def_id).ty.sty { + ty::TyFnDef(def_id, _, f) => { // Some constructors also have type TyFnDef but they are // always instantiated inline and don't result in // translation item. Same for FFI functions. - match tcx.map.get_if_local(def_id) { - Some(hir_map::NodeVariant(_)) | - Some(hir_map::NodeStructCtor(_)) | - Some(hir_map::NodeForeignItem(_)) => false, - Some(_) => true, - None => { - tcx.sess.cstore.variant_kind(def_id).is_none() + if let Some(hir_map::NodeForeignItem(_)) = tcx.map.get_if_local(def_id) { + return false; + } + + if let Some(adt_def) = f.sig.output().skip_binder().ty_adt_def() { + if adt_def.variants.iter().any(|v| def_id == v.did) { + return false; } } } - ty::TyClosure(..) => true, - _ => false - } { - return false; + ty::TyClosure(..) => {} + _ => return false } can_have_local_instance(tcx, def_id) diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index ee2f24d21e0..9db5020747e 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -230,7 +230,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.populate_implementations_for_trait_if_necessary(trait_id); - let trait_item_def_ids = tcx.trait_item_def_ids(trait_id); + let trait_item_def_ids = tcx.impl_or_trait_items(trait_id); trait_item_def_ids .iter() diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index e9f324c0b08..999433db240 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -247,11 +247,17 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { let vtable = common::fulfill_obligation(ccx.shared(), DUMMY_SP, trait_ref); if let traits::VtableImpl(vtable_impl) = vtable { let name = ccx.tcx().item_name(instance.def); - for ac in ccx.tcx().associated_consts(vtable_impl.impl_def_id) { - if ac.name == name { - instance = Instance::new(ac.def_id, vtable_impl.substs); - break; - } + let ac = ccx.tcx().impl_or_trait_items(vtable_impl.impl_def_id) + .iter().filter_map(|id| { + match *id { + ty::ConstTraitItemId(def_id) => { + Some(ccx.tcx().impl_or_trait_item(def_id)) + } + _ => None + } + }).find(|ic| ic.name() == name); + if let Some(ac) = ac { + instance = Instance::new(ac.def_id(), vtable_impl.substs); } } } diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index bcb410e1b8d..71219d82668 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -218,7 +218,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Trait must have a method named `m_name` and it should not have // type parameters or early-bound regions. let tcx = self.tcx; - let method_item = self.trait_item(trait_def_id, m_name).unwrap(); + let method_item = self.impl_or_trait_item(trait_def_id, m_name).unwrap(); let method_ty = method_item.as_opt_method().unwrap(); assert_eq!(method_ty.generics.types.len(), 0); assert_eq!(method_ty.generics.regions.len(), 0); @@ -359,27 +359,14 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { Ok(def) } - /// Find item with name `item_name` defined in `trait_def_id` - /// and return it, or `None`, if no such item. - pub fn trait_item(&self, - trait_def_id: DefId, - item_name: ast::Name) - -> Option> + /// Find item with name `item_name` defined in impl/trait `def_id` + /// and return it, or `None`, if no such item was defined there. + pub fn impl_or_trait_item(&self, + def_id: DefId, + item_name: ast::Name) + -> Option> { - let trait_items = self.tcx.trait_items(trait_def_id); - trait_items.iter() - .find(|item| item.name() == item_name) - .cloned() - } - - pub fn impl_item(&self, - impl_def_id: DefId, - item_name: ast::Name) - -> Option> - { - let impl_items = self.tcx.impl_items.borrow(); - let impl_items = impl_items.get(&impl_def_id).unwrap(); - impl_items + self.tcx.impl_or_trait_items(def_id) .iter() .map(|&did| self.tcx.impl_or_trait_item(did.def_id())) .find(|m| m.name() == item_name) diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index 81e95c91e7f..9fba9bcb757 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -403,7 +403,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { debug!("assemble_inherent_impl_probe {:?}", impl_def_id); - let item = match self.impl_item(impl_def_id) { + let item = match self.impl_or_trait_item(impl_def_id) { Some(m) => m, None => { return; } // No method with correct name on this impl }; @@ -555,7 +555,7 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { let tcx = self.tcx; for bound_trait_ref in traits::transitive_bounds(tcx, bounds) { - let item = match self.trait_item(bound_trait_ref.def_id()) { + let item = match self.impl_or_trait_item(bound_trait_ref.def_id()) { Some(v) => v, None => { continue; } }; @@ -1292,18 +1292,12 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { self.tcx.erase_late_bound_regions(value) } - fn impl_item(&self, impl_def_id: DefId) - -> Option> + /// Find item with name `item_name` defined in impl/trait `def_id` + /// and return it, or `None`, if no such item was defined there. + fn impl_or_trait_item(&self, def_id: DefId) + -> Option> { - self.fcx.impl_item(impl_def_id, self.item_name) - } - - /// Find item with name `item_name` defined in `trait_def_id` - /// and return it, or `None`, if no such item. - fn trait_item(&self, trait_def_id: DefId) - -> Option> - { - self.fcx.trait_item(trait_def_id, self.item_name) + self.fcx.impl_or_trait_item(def_id, self.item_name) } } diff --git a/src/librustc_typeck/check/method/suggest.rs b/src/librustc_typeck/check/method/suggest.rs index 3692d6fbf73..7ec49180702 100644 --- a/src/librustc_typeck/check/method/suggest.rs +++ b/src/librustc_typeck/check/method/suggest.rs @@ -16,9 +16,8 @@ use CrateCtxt; use check::{FnCtxt}; use rustc::hir::map as hir_map; use rustc::ty::{self, Ty, ToPolyTraitRef, ToPredicate, TypeFoldable}; -use middle::cstore; use hir::def::Def; -use hir::def_id::DefId; +use hir::def_id::{CRATE_DEF_INDEX, DefId}; use middle::lang_items::FnOnceTraitLangItem; use rustc::ty::subst::Substs; use rustc::traits::{Obligation, SelectionContext}; @@ -92,9 +91,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { CandidateSource::ImplSource(impl_did) => { // Provide the best span we can. Use the item, if local to crate, else // the impl, if local to crate (item may be defaulted), else nothing. - let item = self.impl_item(impl_did, item_name) + let item = self.impl_or_trait_item(impl_did, item_name) .or_else(|| { - self.trait_item( + self.impl_or_trait_item( self.tcx.impl_trait_ref(impl_did).unwrap().def_id, item_name @@ -127,7 +126,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } CandidateSource::TraitSource(trait_did) => { - let item = self.trait_item(trait_did, item_name).unwrap(); + let item = self.impl_or_trait_item(trait_did, item_name).unwrap(); let item_span = self.tcx.map.def_id_span(item.def_id(), span); span_note!(err, item_span, "candidate #{} is defined in the trait `{}`", @@ -321,7 +320,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // implementing a trait would be legal but is rejected // here). (type_is_local || info.def_id.is_local()) - && self.trait_item(info.def_id, item_name).is_some() + && self.impl_or_trait_item(info.def_id, item_name).is_some() }) .collect::>(); @@ -449,34 +448,30 @@ pub fn all_traits<'a>(ccx: &'a CrateCtxt) -> AllTraits<'a> { // Cross-crate: let mut external_mods = FnvHashSet(); - fn handle_external_def(traits: &mut AllTraitsVec, + fn handle_external_def(ccx: &CrateCtxt, + traits: &mut AllTraitsVec, external_mods: &mut FnvHashSet, - ccx: &CrateCtxt, - cstore: &for<'a> cstore::CrateStore<'a>, - dl: cstore::DefLike) { - match dl { - cstore::DlDef(Def::Trait(did)) => { + def: Def) { + match def { + Def::Trait(did) => { traits.push(TraitInfo::new(did)); } - cstore::DlDef(Def::Mod(did)) => { + Def::Mod(did) => { if !external_mods.insert(did) { return; } - for child in cstore.item_children(did) { - handle_external_def(traits, external_mods, - ccx, cstore, child.def) + for child in ccx.tcx.sess.cstore.item_children(did) { + handle_external_def(ccx, traits, external_mods, child.def) } } _ => {} } } - let cstore = &*ccx.tcx.sess.cstore; - for cnum in ccx.tcx.sess.cstore.crates() { - for child in cstore.crate_top_level_items(cnum) { - handle_external_def(&mut traits, &mut external_mods, - ccx, cstore, child.def) - } + handle_external_def(ccx, &mut traits, &mut external_mods, Def::Mod(DefId { + krate: cnum, + index: CRATE_DEF_INDEX + })); } *ccx.all_traits.borrow_mut() = Some(traits); diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index 26c33c00b9c..fb077d279c9 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -39,6 +39,8 @@ use rustc::hir::intravisit; use rustc::hir::{Item, ItemImpl}; use rustc::hir; +use std::rc::Rc; + mod orphan; mod overlap; mod unsafety; @@ -156,7 +158,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { } } - tcx.impl_items.borrow_mut().insert(impl_did, impl_items); + tcx.impl_or_trait_item_ids.borrow_mut().insert(impl_did, Rc::new(impl_items)); } fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) { @@ -208,7 +210,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { tcx.populate_implementations_for_trait_if_necessary(drop_trait); let drop_trait = tcx.lookup_trait_def(drop_trait); - let impl_items = tcx.impl_items.borrow(); + let impl_items = tcx.impl_or_trait_item_ids.borrow(); drop_trait.for_each_impl(tcx, |impl_did| { let items = impl_items.get(&impl_did).unwrap(); diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 890b6c72e6f..9d072491cc2 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -55,12 +55,12 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { }) } - let impl_items = self.tcx.impl_items.borrow(); + let impl_items = self.tcx.impl_or_trait_item_ids.borrow(); - for item1 in &impl_items[&impl1] { + for item1 in &impl_items[&impl1][..] { let (name, namespace) = name_and_namespace(self.tcx, item1); - for item2 in &impl_items[&impl2] { + for item2 in &impl_items[&impl2][..] { if (name, namespace) == name_and_namespace(self.tcx, item2) { let msg = format!("duplicate definitions with name `{}`", name); let node_id = self.tcx.map.as_local_node_id(item1.def_id()).unwrap(); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index 04aca8c0947..fa052bec7be 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -563,6 +563,7 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, vis: &hir::Visibility, sig: &hir::MethodSig, defaultness: hir::Defaultness, + has_body: bool, untransformed_rcvr_ty: Ty<'tcx>, rcvr_ty_predicates: &ty::GenericPredicates<'tcx>) { let def_id = ccx.tcx.map.local_def_id(id); @@ -580,15 +581,18 @@ fn convert_method<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, sig, untransformed_rcvr_ty, anon_scope) }; - let ty_method = ty::Method::new(name, - ty_generics, - ty_generic_predicates, - fty, - explicit_self_category, - ty::Visibility::from_hir(vis, id, ccx.tcx), - defaultness, - def_id, - container); + let ty_method = ty::Method { + name: name, + generics: ty_generics, + predicates: ty_generic_predicates, + fty: fty, + explicit_self: explicit_self_category, + vis: ty::Visibility::from_hir(vis, id, ccx.tcx), + defaultness: defaultness, + has_body: has_body, + def_id: def_id, + container: container, + }; let substs = mk_item_substs(&ccx.icx(&(rcvr_ty_predicates, &sig.generics)), ccx.tcx.map.span(id), def_id); @@ -843,7 +847,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { convert_method(ccx, ImplContainer(def_id), impl_item.name, impl_item.id, method_vis, - sig, impl_item.defaultness, selfty, + sig, impl_item.defaultness, true, selfty, &ty_predicates); } } @@ -905,7 +909,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { // Convert all the methods for trait_item in trait_items { - if let hir::MethodTraitItem(ref sig, _) = trait_item.node { + if let hir::MethodTraitItem(ref sig, ref body) = trait_item.node { convert_method(ccx, container, trait_item.name, @@ -913,6 +917,7 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { &hir::Inherited, sig, hir::Defaultness::Default, + body.is_some(), tcx.mk_self_type(), &trait_predicates); @@ -928,8 +933,8 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { hir::TypeTraitItem(..) => ty::TypeTraitItemId(def_id) } }).collect()); - tcx.trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), - trait_item_def_ids); + tcx.impl_or_trait_item_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), + trait_item_def_ids); }, hir::ItemStruct(ref struct_def, _) | hir::ItemUnion(ref struct_def, _) => { diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index 709e3698924..e992861b77b 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -15,7 +15,6 @@ use std::iter::once; use syntax::ast; use rustc::hir; -use rustc::middle::cstore; use rustc::hir::def::Def; use rustc::hir::def_id::DefId; use rustc::hir::print as pprust; @@ -96,12 +95,12 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, Def::TyAlias(did) => { record_extern_fqn(cx, did, clean::TypeTypedef); ret.extend(build_impls(cx, tcx, did)); - build_type(cx, tcx, did) + clean::TypedefItem(build_type_alias(cx, tcx, did), false) } Def::Enum(did) => { record_extern_fqn(cx, did, clean::TypeEnum); ret.extend(build_impls(cx, tcx, did)); - build_type(cx, tcx, did) + clean::EnumItem(build_enum(cx, tcx, did)) } // Assume that the enum type is reexported next to the variant, and // variants don't show up in documentation specially. @@ -200,6 +199,18 @@ fn build_external_function<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx } } +fn build_enum<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, + did: DefId) -> clean::Enum { + let t = tcx.lookup_item_type(did); + let predicates = tcx.lookup_predicates(did); + + clean::Enum { + generics: (t.generics, &predicates).clean(cx), + variants_stripped: false, + variants: tcx.lookup_adt_def(did).variants.clean(cx), + } +} + fn build_struct<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, did: DefId) -> clean::Struct { let t = tcx.lookup_item_type(did); @@ -232,25 +243,15 @@ fn build_union<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, } } -fn build_type<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, - did: DefId) -> clean::ItemEnum { +fn build_type_alias<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, + did: DefId) -> clean::Typedef { let t = tcx.lookup_item_type(did); let predicates = tcx.lookup_predicates(did); - match t.ty.sty { - ty::TyAdt(edef, _) if edef.is_enum() && !tcx.sess.cstore.is_typedef(did) => { - return clean::EnumItem(clean::Enum { - generics: (t.generics, &predicates).clean(cx), - variants_stripped: false, - variants: edef.variants.clean(cx), - }) - } - _ => {} - } - clean::TypedefItem(clean::Typedef { + clean::Typedef { type_: t.ty.clean(cx), generics: (t.generics, &predicates).clean(cx), - }, false) + } } pub fn build_impls<'a, 'tcx>(cx: &DocContext, @@ -264,32 +265,49 @@ pub fn build_impls<'a, 'tcx>(cx: &DocContext, build_impl(cx, tcx, did, &mut impls); } } - - // If this is the first time we've inlined something from this crate, then - // we inline *all* impls from the crate into this crate. Note that there's + // If this is the first time we've inlined something from another crate, then + // we inline *all* impls from all the crates into this crate. Note that there's // currently no way for us to filter this based on type, and we likely need // many impls for a variety of reasons. // // Primarily, the impls will be used to populate the documentation for this // type being inlined, but impls can also be used when generating // documentation for primitives (no way to find those specifically). - if cx.populated_crate_impls.borrow_mut().insert(did.krate) { - for item in tcx.sess.cstore.crate_top_level_items(did.krate) { - populate_impls(cx, tcx, item.def, &mut impls); - } + if cx.populated_all_crate_impls.get() { + return impls; + } - fn populate_impls<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, - def: cstore::DefLike, - impls: &mut Vec) { - match def { - cstore::DlImpl(did) => build_impl(cx, tcx, did, impls), - cstore::DlDef(Def::Mod(did)) => { - for item in tcx.sess.cstore.item_children(did) { - populate_impls(cx, tcx, item.def, impls) - } - } - _ => {} - } + cx.populated_all_crate_impls.set(true); + + for did in tcx.sess.cstore.implementations_of_trait(None) { + build_impl(cx, tcx, did, &mut impls); + } + + // Also try to inline primitive impls from other crates. + let primitive_impls = [ + tcx.lang_items.isize_impl(), + tcx.lang_items.i8_impl(), + tcx.lang_items.i16_impl(), + tcx.lang_items.i32_impl(), + tcx.lang_items.i64_impl(), + tcx.lang_items.usize_impl(), + tcx.lang_items.u8_impl(), + tcx.lang_items.u16_impl(), + tcx.lang_items.u32_impl(), + tcx.lang_items.u64_impl(), + tcx.lang_items.f32_impl(), + tcx.lang_items.f64_impl(), + tcx.lang_items.char_impl(), + tcx.lang_items.str_impl(), + tcx.lang_items.slice_impl(), + tcx.lang_items.slice_impl(), + tcx.lang_items.const_ptr_impl() + ]; + + for def_id in primitive_impls.iter().filter_map(|&def_id| def_id) { + if !def_id.is_local() { + tcx.populate_implementations_for_primitive_if_necessary(def_id); + build_impl(cx, tcx, def_id, &mut impls); } } @@ -348,7 +366,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, } let predicates = tcx.lookup_predicates(did); - let trait_items = tcx.sess.cstore.impl_items(did) + let trait_items = tcx.sess.cstore.impl_or_trait_items(did) .iter() .filter_map(|did| { let did = did.def_id(); @@ -453,7 +471,7 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, for_: for_, generics: (ty.generics, &predicates).clean(cx), items: trait_items, - polarity: polarity.map(|p| { p.clean(cx) }), + polarity: Some(polarity.clean(cx)), }), source: clean::Span::empty(), name: None, @@ -482,19 +500,17 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut visited = FnvHashSet(); for item in tcx.sess.cstore.item_children(did) { match item.def { - cstore::DlDef(Def::ForeignMod(did)) => { + Def::ForeignMod(did) => { fill_in(cx, tcx, did, items); } - cstore::DlDef(def) if item.vis == ty::Visibility::Public => { - if !visited.insert(def) { continue } - if let Some(i) = try_inline_def(cx, tcx, def) { - items.extend(i) + def => { + if item.vis == ty::Visibility::Public { + if !visited.insert(def) { continue } + if let Some(i) = try_inline_def(cx, tcx, def) { + items.extend(i) + } } } - cstore::DlDef(..) => {} - // All impls were inlined above - cstore::DlImpl(..) => {} - cstore::DlField => panic!("unimplemented field"), } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7eb7b24015e..f9d7eb50eda 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -33,7 +33,6 @@ use syntax::print::pprust as syntax_pprust; use syntax_pos::{self, DUMMY_SP, Pos}; use rustc_trans::back::link; -use rustc::middle::cstore; use rustc::middle::privacy::AccessLevels; use rustc::middle::resolve_lifetime::DefRegion::*; use rustc::hir::def::Def; @@ -239,9 +238,10 @@ impl Clean for CrateNum { fn clean(&self, cx: &DocContext) -> ExternalCrate { let mut primitives = Vec::new(); cx.tcx_opt().map(|tcx| { - for item in tcx.sess.cstore.crate_top_level_items(self.0) { + let root = DefId { krate: self.0, index: CRATE_DEF_INDEX }; + for item in tcx.sess.cstore.item_children(root) { let did = match item.def { - cstore::DlDef(Def::Mod(did)) => did, + Def::Mod(did) => did, _ => continue }; let attrs = inline::load_attrs(cx, tcx, did); @@ -1877,11 +1877,9 @@ impl Clean for hir::StructField { impl<'tcx> Clean for ty::FieldDefData<'tcx, 'static> { fn clean(&self, cx: &DocContext) -> Item { - // FIXME: possible O(n^2)-ness! Not my fault. - let attr_map = cx.tcx().sess.cstore.crate_struct_field_attrs(self.did.krate); Item { name: Some(self.name).clean(cx), - attrs: attr_map.get(&self.did).unwrap_or(&Vec::new()).clean(cx), + attrs: cx.tcx().get_attrs(self.did).clean(cx), source: Span::empty(), visibility: self.vis.clean(cx), stability: get_stability(cx, self.did), diff --git a/src/librustdoc/core.rs b/src/librustdoc/core.rs index 399702003ea..c52497dc89b 100644 --- a/src/librustdoc/core.rs +++ b/src/librustdoc/core.rs @@ -13,13 +13,13 @@ use rustc_lint; use rustc_driver::{driver, target_features, abort_on_err}; use rustc::dep_graph::DepGraph; use rustc::session::{self, config}; -use rustc::hir::def_id::{CrateNum, DefId}; +use rustc::hir::def_id::DefId; use rustc::hir::def::Def; use rustc::middle::privacy::AccessLevels; use rustc::ty::{self, TyCtxt}; use rustc::hir::map as hir_map; use rustc::lint; -use rustc::util::nodemap::{FnvHashMap, FnvHashSet}; +use rustc::util::nodemap::FnvHashMap; use rustc_trans::back::link; use rustc_resolve as resolve; use rustc_metadata::cstore::CStore; @@ -53,7 +53,7 @@ pub struct DocContext<'a, 'tcx: 'a> { pub map: &'a hir_map::Map<'tcx>, pub maybe_typed: MaybeTyped<'a, 'tcx>, pub input: Input, - pub populated_crate_impls: RefCell>, + pub populated_all_crate_impls: Cell, pub deref_trait_did: Cell>, pub deref_mut_trait_did: Cell>, // Note that external items for which `doc(hidden)` applies to are shown as @@ -205,7 +205,7 @@ pub fn run_core(search_paths: SearchPaths, map: &tcx.map, maybe_typed: Typed(tcx), input: input, - populated_crate_impls: Default::default(), + populated_all_crate_impls: Cell::new(false), deref_trait_did: Cell::new(None), deref_mut_trait_did: Cell::new(None), access_levels: RefCell::new(access_levels), diff --git a/src/librustdoc/test.rs b/src/librustdoc/test.rs index 3d2caeda146..4518945dd98 100644 --- a/src/librustdoc/test.rs +++ b/src/librustdoc/test.rs @@ -106,8 +106,8 @@ pub fn run(input: &str, map: &map, maybe_typed: core::NotTyped(&sess), input: input, + populated_all_crate_impls: Cell::new(false), external_traits: Default::default(), - populated_crate_impls: Default::default(), deref_trait_did: Cell::new(None), deref_mut_trait_did: Cell::new(None), access_levels: Default::default(), diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index cbc556730fb..da11f652b4b 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -8,7 +8,7 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -use rustc::middle::cstore::{CrateStore, ChildItem, DefLike}; +use rustc::middle::cstore::{CrateStore, ChildItem}; use rustc::middle::privacy::{AccessLevels, AccessLevel}; use rustc::hir::def::Def; use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; @@ -66,39 +66,32 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> { pub fn visit_mod(&mut self, did: DefId) { for item in self.cstore.item_children(did) { - if let DefLike::DlDef(def) = item.def { - match def { - Def::Mod(did) | - Def::ForeignMod(did) | - Def::Trait(did) | - Def::Struct(did) | - Def::Union(did) | - Def::Enum(did) | - Def::TyAlias(did) | - Def::Fn(did) | - Def::Method(did) | - Def::Static(did, _) | - Def::Const(did) => self.visit_item(did, item), - _ => {} - } + match item.def { + Def::Mod(did) | + Def::ForeignMod(did) | + Def::Trait(did) | + Def::Struct(did) | + Def::Union(did) | + Def::Enum(did) | + Def::TyAlias(did) | + Def::Fn(did) | + Def::Method(did) | + Def::Static(did, _) | + Def::Const(did) => self.visit_item(did, item), + _ => {} } } } fn visit_item(&mut self, did: DefId, item: ChildItem) { let inherited_item_level = match item.def { - DefLike::DlImpl(..) | DefLike::DlField => unreachable!(), - DefLike::DlDef(def) => { - match def { - Def::ForeignMod(..) => self.prev_level, - _ => if item.vis == Visibility::Public { self.prev_level } else { None } - } - } + Def::ForeignMod(..) => self.prev_level, + _ => if item.vis == Visibility::Public { self.prev_level } else { None } }; let item_level = self.update(did, inherited_item_level); - if let DefLike::DlDef(Def::Mod(did)) = item.def { + if let Def::Mod(did) = item.def { let orig_level = self.prev_level; self.prev_level = item_level;