diff --git a/src/librustc/hir/def.rs b/src/librustc/hir/def.rs index fddf09c9905..dec8ea8a29c 100644 --- a/src/librustc/hir/def.rs +++ b/src/librustc/hir/def.rs @@ -18,15 +18,14 @@ pub enum Def { Fn(DefId), SelfTy(Option /* trait */, Option /* impl */), Mod(DefId), - ForeignMod(DefId), Static(DefId, bool /* is_mutbl */), Const(DefId), AssociatedConst(DefId), Local(DefId), - Variant(DefId /* enum */, DefId /* variant */), + Variant(DefId), Enum(DefId), TyAlias(DefId), - AssociatedTy(DefId /* trait */, DefId), + AssociatedTy(DefId), Trait(DefId), PrimTy(hir::PrimTy), TyParam(DefId), @@ -101,8 +100,8 @@ pub struct Export { impl Def { pub fn def_id(&self) -> DefId { match *self { - Def::Fn(id) | Def::Mod(id) | Def::ForeignMod(id) | Def::Static(id, _) | - Def::Variant(_, id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(_, id) | + Def::Fn(id) | Def::Mod(id) | Def::Static(id, _) | + Def::Variant(id) | Def::Enum(id) | Def::TyAlias(id) | Def::AssociatedTy(id) | Def::TyParam(id) | Def::Struct(id) | Def::Union(id) | Def::Trait(id) | Def::Method(id) | Def::Const(id) | Def::AssociatedConst(id) | Def::Local(id) | Def::Upvar(id, ..) => { @@ -122,7 +121,6 @@ impl Def { match *self { Def::Fn(..) => "function", Def::Mod(..) => "module", - Def::ForeignMod(..) => "foreign module", Def::Static(..) => "static", Def::Variant(..) => "variant", Def::Enum(..) => "enum", diff --git a/src/librustc/hir/pat_util.rs b/src/librustc/hir/pat_util.rs index a63bf14cb02..dec41fdfc3b 100644 --- a/src/librustc/hir/pat_util.rs +++ b/src/librustc/hir/pat_util.rs @@ -174,7 +174,7 @@ pub fn necessary_variants(dm: &DefMap, pat: &hir::Pat) -> Vec { PatKind::Path(..) | PatKind::Struct(..) => { match dm.get(&p.id) { - Some(&PathResolution { base_def: Def::Variant(_, id), .. }) => { + Some(&PathResolution { base_def: Def::Variant(id), .. }) => { variants.push(id); } _ => () diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index e844ec37dc7..87fdc858cf0 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -135,11 +135,9 @@ pub trait CrateStore<'tcx> { fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx>; fn item_variances(&self, def: DefId) -> Vec; - fn repr_attrs(&self, def: DefId) -> Vec; fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Ty<'tcx>; fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap>; - fn item_name(&self, def: DefId) -> ast::Name; fn opt_item_name(&self, def: DefId) -> Option; fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::GenericPredicates<'tcx>; @@ -150,7 +148,7 @@ pub trait CrateStore<'tcx> { fn item_attrs(&self, def_id: DefId) -> Vec; fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>; fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>; - fn method_arg_names(&self, did: DefId) -> Vec; + fn fn_arg_names(&self, did: DefId) -> Vec; fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec; // trait info @@ -211,7 +209,6 @@ pub trait CrateStore<'tcx> { fn def_key(&self, def: DefId) -> hir_map::DefKey; fn relative_def_path(&self, def: 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; @@ -297,13 +294,11 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { fn closure_ty<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> ty::ClosureTy<'tcx> { bug!("closure_ty") } fn item_variances(&self, def: DefId) -> Vec { bug!("item_variances") } - fn repr_attrs(&self, def: DefId) -> Vec { bug!("repr_attrs") } fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Ty<'tcx> { bug!("item_type") } fn visible_parent_map<'a>(&'a self) -> ::std::cell::RefMut<'a, DefIdMap> { bug!("visible_parent_map") } - fn item_name(&self, def: DefId) -> ast::Name { bug!("item_name") } fn opt_item_name(&self, def: DefId) -> Option { bug!("opt_item_name") } fn item_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::GenericPredicates<'tcx> { bug!("item_predicates") } @@ -316,7 +311,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { { bug!("trait_def") } fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx> { bug!("adt_def") } - fn method_arg_names(&self, did: DefId) -> Vec { bug!("method_arg_names") } + fn fn_arg_names(&self, did: DefId) -> Vec { bug!("fn_arg_names") } fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec { vec![] } // trait info @@ -393,8 +388,6 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { } 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") } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 70232d4f01e..30a0c6a9dc9 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -108,8 +108,10 @@ impl<'a, 'tcx> MarkSymbolVisitor<'a, 'tcx> { _ if self.ignore_non_const_paths => (), Def::PrimTy(_) => (), Def::SelfTy(..) => (), - Def::Variant(enum_id, variant_id) => { - self.check_def_id(enum_id); + Def::Variant(variant_id) => { + if let Some(enum_id) = self.tcx.parent_def_id(variant_id) { + self.check_def_id(enum_id); + } if !self.ignore_variant_stack.contains(&variant_id) { self.check_def_id(variant_id); } diff --git a/src/librustc/middle/expr_use_visitor.rs b/src/librustc/middle/expr_use_visitor.rs index ec3fe390317..5b5c3da8f05 100644 --- a/src/librustc/middle/expr_use_visitor.rs +++ b/src/librustc/middle/expr_use_visitor.rs @@ -1003,7 +1003,8 @@ impl<'a, 'gcx, 'tcx> ExprUseVisitor<'a, 'gcx, 'tcx> { // the leaves of the pattern tree structure. return_if_err!(mc.cat_pattern(cmt_discr, pat, |mc, cmt_pat, pat| { match tcx.expect_def_or_none(pat.id) { - Some(Def::Variant(enum_did, variant_did)) => { + Some(Def::Variant(variant_did)) => { + let enum_did = tcx.parent_def_id(variant_did).unwrap(); let downcast_cmt = if tcx.lookup_adt_def(enum_did).is_univariant() { cmt_pat } else { diff --git a/src/librustc/middle/mem_categorization.rs b/src/librustc/middle/mem_categorization.rs index 26cc6007ed0..340a5ac8f87 100644 --- a/src/librustc/middle/mem_categorization.rs +++ b/src/librustc/middle/mem_categorization.rs @@ -529,7 +529,7 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { Ok(self.cat_rvalue_node(id, span, expr_ty)) } - Def::Mod(_) | Def::ForeignMod(_) | + Def::Mod(_) | Def::Trait(_) | Def::Enum(..) | Def::TyAlias(..) | Def::PrimTy(_) | Def::TyParam(..) | Def::Label(_) | Def::SelfTy(..) | @@ -1077,18 +1077,23 @@ impl<'a, 'gcx, 'tcx> MemCategorizationContext<'a, 'gcx, 'tcx> { // alone) because PatKind::Struct can also refer to variants. let cmt = match self.tcx().expect_def_or_none(pat.id) { Some(Def::Err) => return Err(()), - Some(Def::Variant(enum_did, variant_did)) + Some(Def::Variant(variant_did)) => { // univariant enums do not need downcasts - if !self.tcx().lookup_adt_def(enum_did).is_univariant() => { + let enum_did = self.tcx().parent_def_id(variant_did).unwrap(); + if !self.tcx().lookup_adt_def(enum_did).is_univariant() { self.cat_downcast(pat, cmt.clone(), cmt.ty, variant_did) + } else { + cmt } + } _ => cmt }; match pat.node { PatKind::TupleStruct(_, ref subpats, ddpos) => { let expected_len = match self.tcx().expect_def(pat.id) { - Def::Variant(enum_def, def_id) => { + Def::Variant(def_id) => { + let enum_def = self.tcx().parent_def_id(def_id).unwrap(); self.tcx().lookup_adt_def(enum_def).variant_with_id(def_id).fields.len() } Def::Struct(..) => { diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 1c9238646df..0faf6750abd 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -1404,13 +1404,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Obtain the representation annotation for a struct definition. pub fn lookup_repr_hints(self, did: DefId) -> Rc> { self.repr_hint_cache.memoize(did, || { - Rc::new(if did.is_local() { - self.get_attrs(did).iter().flat_map(|meta| { - attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter() - }).collect() - } else { - self.sess.cstore.repr_attrs(did) - }) + Rc::new(self.get_attrs(did).iter().flat_map(|meta| { + attr::find_repr_attrs(self.sess.diagnostic(), meta).into_iter() + }).collect()) }) } } diff --git a/src/librustc/ty/item_path.rs b/src/librustc/ty/item_path.rs index e4247a60b15..5f121b568c3 100644 --- a/src/librustc/ty/item_path.rs +++ b/src/librustc/ty/item_path.rs @@ -303,7 +303,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// Returns the def-id of `def_id`'s parent in the def tree. If /// this returns `None`, then `def_id` represents a crate root or /// inlined root. - fn parent_def_id(&self, def_id: DefId) -> Option { + pub fn parent_def_id(self, def_id: DefId) -> Option { let key = self.def_key(def_id); key.parent.map(|index| DefId { krate: def_id.krate, index: index }) } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 8aba6329b09..8171a99beb9 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -193,7 +193,7 @@ impl<'tcx> ImplOrTraitItem<'tcx> { match *self { ConstTraitItem(ref associated_const) => Def::AssociatedConst(associated_const.def_id), MethodTraitItem(ref method) => Def::Method(method.def_id), - TypeTraitItem(ref ty) => Def::AssociatedTy(ty.container.id(), ty.def_id), + TypeTraitItem(ref ty) => Def::AssociatedTy(ty.def_id), } } @@ -1666,7 +1666,7 @@ impl<'a, 'gcx, 'tcx, 'container> AdtDefData<'gcx, 'container> { pub fn variant_of_def(&self, def: Def) -> &VariantDefData<'gcx, 'container> { match def { - Def::Variant(_, vid) => self.variant_with_id(vid), + Def::Variant(vid) => self.variant_with_id(vid), Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => self.struct_variant(), _ => bug!("unexpected def {:?} in variant_of_def", def) @@ -2325,7 +2325,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // or variant or their constructors, panics otherwise. pub fn expect_variant_def(self, def: Def) -> VariantDef<'tcx> { match def { - Def::Variant(enum_did, did) => { + Def::Variant(did) => { + let enum_did = self.parent_def_id(did).unwrap(); self.lookup_adt_def(enum_did).variant_with_id(did) } Def::Struct(did) | Def::Union(did) => { @@ -2387,7 +2388,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { if let Some(id) = self.map.as_local_node_id(id) { self.map.name(id) } else { - self.sess.cstore.item_name(id) + self.sess.cstore.opt_item_name(id).unwrap_or_else(|| { + bug!("item_name: no name for {:?}", self.def_path(id)); + }) } } @@ -2631,11 +2634,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let trait_ref = self.impl_trait_ref(impl_def_id).unwrap(); // Record the trait->implementation mapping. - if let Some(parent) = self.sess.cstore.impl_parent(impl_def_id) { - def.record_remote_impl(self, impl_def_id, trait_ref, parent); - } else { - def.record_remote_impl(self, impl_def_id, trait_ref, trait_id); - } + let parent = self.sess.cstore.impl_parent(impl_def_id).unwrap_or(trait_id); + def.record_remote_impl(self, impl_def_id, trait_ref, parent); // For any methods that use a default implementation, add them to // the map. This is a bit unfortunate. diff --git a/src/librustc_const_eval/check_match.rs b/src/librustc_const_eval/check_match.rs index 8af06286189..eb74936d8c9 100644 --- a/src/librustc_const_eval/check_match.rs +++ b/src/librustc_const_eval/check_match.rs @@ -801,7 +801,7 @@ fn pat_constructors(cx: &MatchCheckCtxt, p: &Pat, match pat.node { PatKind::Struct(..) | PatKind::TupleStruct(..) | PatKind::Path(..) => match cx.tcx.expect_def(pat.id) { - Def::Variant(_, id) => vec![Variant(id)], + Def::Variant(id) => vec![Variant(id)], Def::Struct(..) | Def::Union(..) | Def::TyAlias(..) | Def::AssociatedTy(..) => vec![Single], Def::Const(..) | Def::AssociatedConst(..) => @@ -913,7 +913,7 @@ pub fn specialize<'a, 'b, 'tcx>( Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat_span, "const pattern should've \ been rewritten"), - Def::Variant(_, id) if *constructor != Variant(id) => None, + Def::Variant(id) if *constructor != Variant(id) => None, Def::Variant(..) | Def::Struct(..) => Some(Vec::new()), def => span_bug!(pat_span, "specialize: unexpected \ definition {:?}", def), @@ -925,7 +925,7 @@ pub fn specialize<'a, 'b, 'tcx>( Def::Const(..) | Def::AssociatedConst(..) => span_bug!(pat_span, "const pattern should've \ been rewritten"), - Def::Variant(_, id) if *constructor != Variant(id) => None, + Def::Variant(id) if *constructor != Variant(id) => None, Def::Variant(..) | Def::Struct(..) => { match ddpos { Some(ddpos) => { diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index aa53fdd6e7e..dce3882004c 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -57,7 +57,6 @@ macro_rules! math { } fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - enum_def: DefId, variant_def: DefId) -> Option<&'tcx Expr> { fn variant_expr<'a>(variants: &'a [hir::Variant], id: ast::NodeId) @@ -70,8 +69,8 @@ fn lookup_variant_by_id<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, None } - if let Some(enum_node_id) = tcx.map.as_local_node_id(enum_def) { - let variant_node_id = tcx.map.as_local_node_id(variant_def).unwrap(); + if let Some(variant_node_id) = tcx.map.as_local_node_id(variant_def) { + let enum_node_id = tcx.map.get_parent(variant_node_id); match tcx.map.find(enum_node_id) { None => None, Some(ast_map::NodeItem(it)) => match it.node { @@ -289,7 +288,7 @@ pub fn const_expr_to_pat<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } let path = match def { Def::Struct(def_id) => def_to_path(tcx, def_id), - Def::Variant(_, variant_did) => def_to_path(tcx, variant_did), + Def::Variant(variant_did) => def_to_path(tcx, variant_did), Def::Fn(..) | Def::Method(..) => return Ok(P(hir::Pat { id: expr.id, node: PatKind::Lit(P(expr.clone())), @@ -808,8 +807,8 @@ pub fn eval_const_expr_partial<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, signal!(e, NonConstPath); } }, - Def::Variant(enum_def, variant_def) => { - if let Some(const_expr) = lookup_variant_by_id(tcx, enum_def, variant_def) { + Def::Variant(variant_def) => { + if let Some(const_expr) = lookup_variant_by_id(tcx, variant_def) { match eval_const_expr_partial(tcx, const_expr, ty_hint, None) { Ok(val) => val, Err(err) => { diff --git a/src/librustc_incremental/calculate_svh/svh_visitor.rs b/src/librustc_incremental/calculate_svh/svh_visitor.rs index af8ec6c6257..9950f470a82 100644 --- a/src/librustc_incremental/calculate_svh/svh_visitor.rs +++ b/src/librustc_incremental/calculate_svh/svh_visitor.rs @@ -602,7 +602,6 @@ impl<'a, 'hash, 'tcx> StrictVersionHashVisitor<'a, 'hash, 'tcx> { // def-id is the same, so it suffices to hash the def-id Def::Fn(..) | Def::Mod(..) | - Def::ForeignMod(..) | Def::Static(..) | Def::Variant(..) | Def::Enum(..) | diff --git a/src/librustc_metadata/astencode.rs b/src/librustc_metadata/astencode.rs index c687353d437..518e6624412 100644 --- a/src/librustc_metadata/astencode.rs +++ b/src/librustc_metadata/astencode.rs @@ -18,7 +18,7 @@ use cstore::CrateMetadata; use decoder::DecodeContext; use encoder::EncodeContext; -use middle::cstore::{InlinedItem, InlinedItemRef}; +use rustc::middle::cstore::{InlinedItem, InlinedItemRef}; use rustc::hir::def; use rustc::hir::def_id::DefId; use rustc::ty::TyCtxt; diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs index 04b9b7f7c67..e068395f729 100644 --- a/src/librustc_metadata/common.rs +++ b/src/librustc_metadata/common.rs @@ -10,29 +10,36 @@ #![allow(non_camel_case_types, non_upper_case_globals)] +use rustc::hir; +use rustc::hir::def; +use rustc::hir::def_id::{DefIndex, DefId}; use rustc::ty; +use rustc::session::config::PanicStrategy; #[derive(Clone, Copy, Debug, PartialEq, RustcEncodable, RustcDecodable)] pub enum Family { ImmStatic, MutStatic, + ForeignImmStatic, + ForeignMutStatic, Fn, + ForeignFn, Method, AssociatedType, Type, Mod, ForeignMod, Enum, - Variant(ty::VariantKind), + Variant, Impl, DefaultImpl, Trait, - Struct(ty::VariantKind), + Struct, Union, - PublicField, - InheritedField, + Field, Const, AssociatedConst, + Closure } // NB: increment this if you change the format of metadata such that @@ -48,68 +55,151 @@ pub fn rustc_version() -> String { ) } +#[derive(RustcEncodable, RustcDecodable)] +pub struct CrateInfo { + pub name: String, + pub triple: String, + pub hash: hir::svh::Svh, + pub disambiguator: String, + pub panic_strategy: PanicStrategy, + pub plugin_registrar_fn: Option, + pub macro_derive_registrar: Option +} + pub mod root_tag { pub const rustc_version: usize = 0x10f; - pub const crate_deps: usize = 0x102; - pub const crate_hash: usize = 0x103; - pub const crate_crate_name: usize = 0x104; - pub const crate_disambiguator: usize = 0x113; - pub const items: usize = 0x100; + + pub const crate_info: usize = 0x104; + pub const index: usize = 0x110; pub const xref_index: usize = 0x111; pub const xref_data: usize = 0x112; - pub const crate_triple: usize = 0x105; + pub const crate_deps: usize = 0x102; pub const dylib_dependency_formats: usize = 0x106; + pub const native_libraries: usize = 0x10a; pub const lang_items: usize = 0x107; pub const lang_items_missing: usize = 0x76; pub const impls: usize = 0x109; - pub const native_libraries: usize = 0x10a; - pub const plugin_registrar_fn: usize = 0x10b; - pub const panic_strategy: usize = 0x114; - pub const macro_derive_registrar: usize = 0x115; pub const reachable_ids: usize = 0x10c; pub const macro_defs: usize = 0x10e; pub const codemap: usize = 0xa1; } +#[derive(RustcEncodable, RustcDecodable)] +pub struct ModData { + pub reexports: Vec +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct VariantData { + pub kind: ty::VariantKind, + pub disr: u64, + + /// If this is a struct's only variant, this + /// is the index of the "struct ctor" item. + pub struct_ctor: Option +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct TraitData { + pub unsafety: hir::Unsafety, + pub paren_sugar: bool, + pub has_default_impl: bool +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct ImplData { + pub polarity: hir::ImplPolarity, + pub parent_impl: Option, + pub coerce_unsized_kind: Option, +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct TraitAssociatedData { + pub has_default: bool +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct ImplAssociatedData { + pub defaultness: hir::Defaultness, + pub constness: hir::Constness +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct FnData { + pub constness: hir::Constness +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct ClosureData { + pub kind: ty::ClosureKind +} + +#[derive(RustcEncodable, RustcDecodable)] +pub enum EntryData { + Other, + Mod(ModData), + Variant(VariantData), + Trait(TraitData), + Impl(ImplData), + TraitAssociated(TraitAssociatedData), + ImplAssociated(ImplAssociatedData), + Fn(FnData), + Closure(ClosureData) +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct TraitTypedData<'tcx> { + pub trait_ref: ty::TraitRef<'tcx> +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct ImplTypedData<'tcx> { + pub trait_ref: Option> +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct MethodTypedData<'tcx> { + pub explicit_self: ty::ExplicitSelfCategory<'tcx> +} + +#[derive(RustcEncodable, RustcDecodable)] +pub struct ClosureTypedData<'tcx> { + pub ty: ty::ClosureTy<'tcx> +} + +#[derive(RustcEncodable, RustcDecodable)] +pub enum EntryTypedData<'tcx> { + Other, + Trait(TraitTypedData<'tcx>), + Impl(ImplTypedData<'tcx>), + Method(MethodTypedData<'tcx>), + Closure(ClosureTypedData<'tcx>) +} + pub mod item_tag { - pub const name: usize = 0x20; - pub const def_index: usize = 0x21; - pub const family: usize = 0x24; - pub const ty: usize = 0x25; - pub const parent_item: usize = 0x28; - pub const is_tuple_struct_ctor: usize = 0x29; - pub const closure_kind: usize = 0x2a; - pub const closure_ty: usize = 0x2b; pub const def_key: usize = 0x2c; + pub const family: usize = 0x24; pub const attributes: usize = 0x101; - pub const trait_ref: usize = 0x3b; - pub const disr_val: usize = 0x3c; - pub const fields: usize = 0x41; - pub const variances: usize = 0x43; - pub const trait_method_explicit_self: usize = 0x45; - pub const ast: usize = 0x50; - pub const mir: usize = 0x52; - pub const trait_item_has_body: usize = 0x70; pub const visibility: usize = 0x78; - pub const inherent_impls: usize = 0x79; pub const children: usize = 0x7b; - pub const method_argument_names: usize = 0x85; pub const stability: usize = 0x88; - pub const repr: usize = 0x89; - pub const struct_ctor: usize = 0x8b; + pub const deprecation: usize = 0xa7; + + pub const ty: usize = 0x25; + pub const inherent_impls: usize = 0x79; + pub const variances: usize = 0x43; pub const generics: usize = 0x8f; pub const predicates: usize = 0x95; - pub const unsafety: usize = 0x9a; - pub const polarity: usize = 0x9d; - pub const paren_sugar: usize = 0xa0; pub const super_predicates: usize = 0xa3; - pub const defaulted_trait: usize = 0xa4; - pub const impl_coerce_unsized_kind: usize = 0xa5; - pub const constness: usize = 0xa6; - pub const deprecation: usize = 0xa7; - pub const defaultness: usize = 0xa8; - pub const parent_impl: usize = 0xa9; + + pub const ast: usize = 0x50; + pub const mir: usize = 0x52; + + pub const data: usize = 0x3c; + pub const typed_data: usize = 0x3d; + + pub const fn_arg_names: usize = 0x85; } /// The shorthand encoding of `Ty` uses `TypeVariants`' variant `usize` diff --git a/src/librustc_metadata/creader.rs b/src/librustc_metadata/creader.rs index 7b6ed4e6b76..dd6ef73ccdb 100644 --- a/src/librustc_metadata/creader.rs +++ b/src/librustc_metadata/creader.rs @@ -12,6 +12,7 @@ //! Validates all used crates and extern libraries and loads their metadata +use common::CrateInfo; use cstore::{self, CStore, CrateSource, MetadataBlob}; use decoder; use loader::{self, CratePaths}; @@ -85,7 +86,7 @@ fn should_link(i: &ast::Item) -> bool { } #[derive(Debug)] -struct CrateInfo { +struct ExternCrateInfo { ident: String, name: String, id: ast::NodeId, @@ -183,7 +184,7 @@ impl<'a> CrateReader<'a> { } } - fn extract_crate_info(&self, i: &ast::Item) -> Option { + fn extract_crate_info(&self, i: &ast::Item) -> Option { match i.node { ast::ItemKind::ExternCrate(ref path_opt) => { debug!("resolving extern crate stmt. ident: {} path_opt: {:?}", @@ -196,7 +197,7 @@ impl<'a> CrateReader<'a> { } None => i.ident.to_string(), }; - Some(CrateInfo { + Some(ExternCrateInfo { ident: i.ident.to_string(), name: name, id: i.id, @@ -258,32 +259,28 @@ impl<'a> CrateReader<'a> { fn verify_no_symbol_conflicts(&self, span: Span, - metadata: &MetadataBlob) { - let disambiguator = decoder::get_crate_disambiguator(metadata.as_slice()); - let crate_name = decoder::get_crate_name(metadata.as_slice()); - + info: &CrateInfo) { // Check for (potential) conflicts with the local crate - if self.local_crate_name == crate_name && - self.sess.local_crate_disambiguator() == &disambiguator[..] { + if self.local_crate_name == info.name && + self.sess.local_crate_disambiguator() == &info.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 \ compiled with the same `-C metadata` arguments. This \ will result in symbol conflicts between the two.", - crate_name) + info.name) } - let svh = decoder::get_crate_hash(metadata.as_slice()); // Check for conflicts with any crate loaded so far self.cstore.iter_crate_data(|_, other| { - if other.name() == crate_name && // same crate-name - other.disambiguator() == disambiguator && // same crate-disambiguator - other.hash() != svh { // but different SVH + if other.name() == info.name && // same crate-name + other.disambiguator() == info.disambiguator && // same crate-disambiguator + other.hash() != info.hash { // but different SVH span_fatal!(self.sess, span, E0523, "found two different crates with name `{}` that are \ not distinguished by differing `-C metadata`. This \ will result in symbol conflicts between the two.", - crate_name) + info.name) } }); } @@ -298,7 +295,8 @@ impl<'a> CrateReader<'a> { -> (CrateNum, Rc, cstore::CrateSource) { info!("register crate `extern crate {} as {}`", name, ident); - self.verify_no_symbol_conflicts(span, &lib.metadata); + let crate_info = decoder::get_crate_info(lib.metadata.as_slice()); + self.verify_no_symbol_conflicts(span, &crate_info); // Claim this crate number and cache it let cnum = self.next_crate_num; @@ -321,9 +319,15 @@ impl<'a> CrateReader<'a> { let cnum_map = self.resolve_crate_deps(root, metadata.as_slice(), cnum, span); + if crate_info.macro_derive_registrar.is_some() { + self.sess.span_err(span, "crates of the `rustc-macro` crate type \ + cannot be linked at runtime"); + } + let cmeta = Rc::new(cstore::CrateMetadata { name: name.to_string(), extern_crate: Cell::new(None), + info: crate_info, index: decoder::load_index(metadata.as_slice()), xref_index: decoder::load_xrefs(metadata.as_slice()), key_map: decoder::load_key_map(metadata.as_slice()), @@ -334,11 +338,6 @@ impl<'a> CrateReader<'a> { explicitly_linked: Cell::new(explicitly_linked), }); - if decoder::get_derive_registrar_fn(cmeta.data.as_slice()).is_some() { - self.sess.span_err(span, "crates of the `rustc-macro` crate type \ - cannot be linked at runtime"); - } - let source = cstore::CrateSource { dylib: dylib, rlib: rlib, @@ -416,13 +415,11 @@ impl<'a> CrateReader<'a> { // Note that we only do this for target triple crates, though, as we // don't want to match a host crate against an equivalent target one // already loaded. + let crate_info = decoder::get_crate_info(library.metadata.as_slice()); if loader.triple == self.sess.opts.target_triple { - let meta_hash = decoder::get_crate_hash(library.metadata.as_slice()); - let meta_name = decoder::get_crate_name(library.metadata.as_slice()) - .to_string(); let mut result = LoadResult::Loaded(library); self.cstore.iter_crate_data(|cnum, data| { - if data.name() == meta_name && meta_hash == data.hash() { + if data.name() == crate_info.name && crate_info.hash == data.hash() { assert!(loader.hash.is_none()); info!("load success, going to previous cnum: {}", cnum); result = LoadResult::Previous(cnum); @@ -497,7 +494,7 @@ impl<'a> CrateReader<'a> { }).collect() } - fn read_extension_crate(&mut self, span: Span, info: &CrateInfo) -> ExtensionCrate { + fn read_extension_crate(&mut self, span: Span, info: &ExternCrateInfo) -> ExtensionCrate { info!("read extension crate {} `extern crate {} as {}` linked={}", info.id, info.name, info.ident, info.should_link); let target_triple = &self.sess.opts.target_triple[..]; @@ -570,11 +567,12 @@ impl<'a> CrateReader<'a> { let ci = self.extract_crate_info(item).unwrap(); let ekrate = self.read_extension_crate(item.span, &ci); + let crate_info = decoder::get_crate_info(ekrate.metadata.as_slice()); let source_name = format!("<{} macros>", item.ident); let mut ret = Macros { macro_rules: Vec::new(), custom_derive_registrar: None, - svh: decoder::get_crate_hash(ekrate.metadata.as_slice()), + svh: crate_info.hash, dylib: None, }; decoder::each_exported_macro(ekrate.metadata.as_slice(), @@ -619,7 +617,7 @@ impl<'a> CrateReader<'a> { true }); - match decoder::get_derive_registrar_fn(ekrate.metadata.as_slice()) { + match crate_info.macro_derive_registrar { Some(id) => ret.custom_derive_registrar = Some(id), // If this crate is not a rustc-macro crate then we might be able to @@ -656,7 +654,7 @@ impl<'a> CrateReader<'a> { /// SVH and DefIndex of the registrar function. pub fn find_plugin_registrar(&mut self, span: Span, name: &str) -> Option<(PathBuf, Svh, DefIndex)> { - let ekrate = self.read_extension_crate(span, &CrateInfo { + let ekrate = self.read_extension_crate(span, &ExternCrateInfo { name: name.to_string(), ident: name.to_string(), id: ast::DUMMY_NODE_ID, @@ -673,13 +671,10 @@ impl<'a> CrateReader<'a> { span_fatal!(self.sess, span, E0456, "{}", &message[..]); } - let svh = decoder::get_crate_hash(ekrate.metadata.as_slice()); - let registrar = - decoder::get_plugin_registrar_fn(ekrate.metadata.as_slice()); - - match (ekrate.dylib.as_ref(), registrar) { + let crate_info = decoder::get_crate_info(ekrate.metadata.as_slice()); + match (ekrate.dylib.as_ref(), crate_info.plugin_registrar_fn) { (Some(dylib), Some(reg)) => { - Some((dylib.to_path_buf(), svh, reg)) + Some((dylib.to_path_buf(), crate_info.hash, reg)) } (None, Some(_)) => { span_err!(self.sess, span, E0457, diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index c4ce7af269d..f650155c035 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -14,10 +14,10 @@ use decoder; use encoder; use loader; -use middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate}; -use middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference}; +use rustc::middle::cstore::{InlinedItem, CrateStore, CrateSource, ChildItem, ExternCrate}; +use rustc::middle::cstore::{NativeLibraryKind, LinkMeta, LinkagePreference}; use rustc::hir::def; -use middle::lang_items; +use rustc::middle::lang_items; use rustc::ty::{self, Ty, TyCtxt}; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, CRATE_DEF_INDEX}; @@ -77,12 +77,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_item_variances(&cdata, def.index) } - fn repr_attrs(&self, def: DefId) -> Vec { - self.dep_graph.read(DepNode::MetaData(def)); - let cdata = self.get_crate_data(def.krate); - decoder::get_repr_attrs(&cdata, def.index) - } - fn item_type<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Ty<'tcx> { @@ -136,23 +130,21 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_adt_def(&cdata, def.index, tcx) } - fn method_arg_names(&self, did: DefId) -> Vec + fn fn_arg_names(&self, did: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(did)); let cdata = self.get_crate_data(did.krate); - decoder::get_method_arg_names(&cdata, did.index) - } - - fn item_name(&self, def: DefId) -> ast::Name { - self.dep_graph.read(DepNode::MetaData(def)); - let cdata = self.get_crate_data(def.krate); - decoder::get_item_name(&cdata, def.index) + decoder::get_fn_arg_names(&cdata, did.index) } fn opt_item_name(&self, def: DefId) -> Option { self.dep_graph.read(DepNode::MetaData(def)); let cdata = self.get_crate_data(def.krate); - decoder::maybe_get_item_name(&cdata, def.index) + if def.index == CRATE_DEF_INDEX { + Some(token::intern(&cdata.name())) + } else { + decoder::maybe_get_item_name(&cdata, def.index) + } } fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec @@ -183,10 +175,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.dep_graph.read(DepNode::MetaData(def_id)); let mut result = vec![]; let crate_data = self.get_crate_data(def_id.krate); - let get_crate_data = |cnum| self.get_crate_data(cnum); - decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data, |def, _, _| { - result.push(def.def_id()); - }); + let get_crate_data = &mut |cnum| self.get_crate_data(cnum); + decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data, + &mut |def, _, _| result.push(def.def_id())); result } @@ -339,20 +330,17 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { fn crate_hash(&self, cnum: CrateNum) -> Svh { - let cdata = self.get_crate_data(cnum); - decoder::get_crate_hash(cdata.data()) + self.get_crate_hash(cnum) } 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())) + token::intern_and_get_ident(&self.get_crate_data(cnum).disambiguator()) } fn plugin_registrar_fn(&self, cnum: CrateNum) -> Option { - let cdata = self.get_crate_data(cnum); - decoder::get_plugin_registrar_fn(cdata.data()).map(|index| DefId { + self.get_crate_data(cnum).info.plugin_registrar_fn.map(|index| DefId { krate: cnum, index: index }) @@ -412,13 +400,6 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { decoder::get_struct_ctor_def_id(&cdata, struct_def_id.index) } - fn tuple_struct_definition_if_ctor(&self, did: DefId) -> Option - { - self.dep_graph.read(DepNode::MetaData(did)); - let cdata = self.get_crate_data(did.krate); - decoder::get_tuple_struct_definition_if_ctor(&cdata, did.index) - } - fn struct_field_names(&self, def: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(def)); @@ -431,8 +412,9 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { self.dep_graph.read(DepNode::MetaData(def_id)); let mut result = vec![]; let crate_data = self.get_crate_data(def_id.krate); - let get_crate_data = |cnum| self.get_crate_data(cnum); - decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data, |def, name, vis| { + let get_crate_data = &mut |cnum| self.get_crate_data(cnum); + decoder::each_child_of_item(&crate_data, def_id.index, get_crate_data, + &mut |def, name, vis| { result.push(ChildItem { def: def, name: name, vis: vis }); }); result @@ -497,45 +479,17 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { }; match inlined { - decoder::FoundAst::NotFound => { + None => { self.inlined_item_cache .borrow_mut() .insert(def_id, None); } - decoder::FoundAst::Found(&InlinedItem::Item(d, ref item)) => { + Some(&InlinedItem::Item(d, ref item)) => { assert_eq!(d, def_id); let inlined_root_node_id = find_inlined_item_root(item.id); cache_inlined_item(def_id, item.id, inlined_root_node_id); } - decoder::FoundAst::FoundParent(parent_did, item) => { - let inlined_root_node_id = find_inlined_item_root(item.id); - cache_inlined_item(parent_did, item.id, inlined_root_node_id); - - match item.node { - hir::ItemEnum(ref ast_def, _) => { - let ast_vs = &ast_def.variants; - let ty_vs = &tcx.lookup_adt_def(parent_did).variants; - assert_eq!(ast_vs.len(), ty_vs.len()); - for (ast_v, ty_v) in ast_vs.iter().zip(ty_vs.iter()) { - cache_inlined_item(ty_v.did, - ast_v.node.data.id(), - inlined_root_node_id); - } - } - hir::ItemStruct(ref struct_def, _) => { - if struct_def.is_struct() { - bug!("instantiate_inline: called on a non-tuple struct") - } else { - cache_inlined_item(def_id, - struct_def.id(), - inlined_root_node_id); - } - } - _ => bug!("instantiate_inline: item has a \ - non-enum, non-struct parent") - } - } - decoder::FoundAst::Found(&InlinedItem::TraitItem(_, ref trait_item)) => { + Some(&InlinedItem::TraitItem(_, ref trait_item)) => { let inlined_root_node_id = find_inlined_item_root(trait_item.id); cache_inlined_item(def_id, trait_item.id, inlined_root_node_id); @@ -548,7 +502,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { tcx.impl_or_trait_items.borrow_mut() .insert(trait_item_def_id, ty_trait_item); } - decoder::FoundAst::Found(&InlinedItem::ImplItem(_, ref impl_item)) => { + Some(&InlinedItem::ImplItem(_, ref impl_item)) => { let inlined_root_node_id = find_inlined_item_root(impl_item.id); cache_inlined_item(def_id, impl_item.id, inlined_root_node_id); } diff --git a/src/librustc_metadata/cstore.rs b/src/librustc_metadata/cstore.rs index 7aa4677353b..c6cbe6db909 100644 --- a/src/librustc_metadata/cstore.rs +++ b/src/librustc_metadata/cstore.rs @@ -39,9 +39,9 @@ use syntax::attr; use syntax::codemap; use syntax_pos; -pub use middle::cstore::{NativeLibraryKind, LinkagePreference}; -pub use middle::cstore::{NativeStatic, NativeFramework, NativeUnknown}; -pub use middle::cstore::{CrateSource, LinkMeta}; +pub use rustc::middle::cstore::{NativeLibraryKind, LinkagePreference}; +pub use rustc::middle::cstore::{NativeStatic, NativeFramework, NativeUnknown}; +pub use rustc::middle::cstore::{CrateSource, LinkMeta}; // A map from external crate numbers (as decoded from some crate file) to // local crate numbers (as generated during this session). Each external @@ -78,6 +78,7 @@ pub struct CrateMetadata { pub cnum: CrateNum, pub codemap_import_info: RefCell>, + pub info: common::CrateInfo, pub index: index::Index, pub xref_index: index::DenseIndex, @@ -143,8 +144,7 @@ impl CStore { } pub fn get_crate_hash(&self, cnum: CrateNum) -> Svh { - let cdata = self.get_crate_data(cnum); - decoder::get_crate_hash(cdata.data()) + self.get_crate_data(cnum).hash() } pub fn set_crate_data(&self, cnum: CrateNum, data: Rc) { @@ -299,11 +299,9 @@ impl CStore { impl CrateMetadata { pub fn data<'a>(&'a self) -> &'a [u8] { self.data.as_slice() } - 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) -> String { - decoder::get_crate_disambiguator(self.data()) - } + pub fn name(&self) -> &str { &self.info.name } + pub fn hash(&self) -> Svh { self.info.hash } + pub fn disambiguator(&self) -> &str { &self.info.disambiguator } pub fn imported_filemaps<'a>(&'a self, codemap: &codemap::CodeMap) -> Ref<'a, Vec> { let filemaps = self.codemap_import_info.borrow(); @@ -352,7 +350,7 @@ impl CrateMetadata { } pub fn panic_strategy(&self) -> PanicStrategy { - decoder::get_panic_strategy(self.data()) + self.info.panic_strategy.clone() } } diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 662236be0f0..f3283451b93 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -15,25 +15,22 @@ use astencode::decode_inlined_item; use cstore::{self, CrateMetadata}; use common::*; -use common::Family::*; -use def_key; use index; use rustc::hir::def_id::CRATE_DEF_INDEX; use rustc::hir::svh::Svh; use rustc::hir::map as hir_map; -use rustc::hir::map::DefKey; +use rustc::hir::map::{DefKey, DefPathData}; use rustc::util::nodemap::FnvHashMap; use rustc::hir; use rustc::hir::intravisit::IdRange; -use rustc::session::config::PanicStrategy; -use middle::cstore::{InlinedItem, LinkagePreference}; -use rustc::hir::def::{self, Def}; +use rustc::middle::cstore::{InlinedItem, LinkagePreference}; +use rustc::hir::def::Def; use rustc::hir::def_id::{CrateNum, DefId, DefIndex, LOCAL_CRATE}; -use middle::lang_items; +use rustc::middle::lang_items; use rustc::ty::{ImplContainer, TraitContainer}; -use rustc::ty::{self, Ty, TyCtxt, TypeFoldable}; +use rustc::ty::{self, Ty, TyCtxt}; use rustc::ty::subst::Substs; use rustc_const_math::ConstInt; @@ -51,6 +48,7 @@ use rbml; use rustc_serialize::{Decodable, Decoder, SpecializedDecoder, opaque}; use syntax::attr; use syntax::ast::{self, NodeId}; +use syntax::parse::token; use syntax_pos::{self, Span, BytePos}; pub struct DecodeContext<'a, 'tcx: 'a> { @@ -101,12 +99,6 @@ impl<'a, 'tcx> DecodeContext<'a, 'tcx> { 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 { @@ -321,6 +313,13 @@ impl CrateMetadata { Some(d) => d } } + + fn local_def_id(&self, index: DefIndex) -> DefId { + DefId { + krate: self.cnum, + index: index + } + } } pub fn load_index(data: &[u8]) -> index::Index { @@ -342,12 +341,10 @@ pub fn load_xrefs(data: &[u8]) -> index::DenseIndex { // 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 { - rbml::Doc::new(data).get(root_tag::items).children().map(|item_doc| { + load_index(data).iter_enumerated(data).map(|(index, pos)| { // load def-key from item - let key = item_def_key(item_doc); - - // load def-index from item - (key, item_doc.get(item_tag::def_index).decoder().decode()) + let key = item_def_key(rbml::Doc::at(data, pos as usize)); + (key, index) }).collect() } @@ -356,38 +353,27 @@ fn item_family(item: rbml::Doc) -> Family { } fn item_visibility(item: rbml::Doc) -> ty::Visibility { - match reader::maybe_get_doc(item, item_tag::visibility) { - None => ty::Visibility::Public, - Some(visibility_doc) => visibility_doc.decoder().decode() - } + item.get(item_tag::visibility).decoder().decode() } -fn item_defaultness(item: rbml::Doc) -> hir::Defaultness { - match reader::maybe_get_doc(item, item_tag::defaultness) { - None => hir::Defaultness::Default, // should occur only for default impls on traits - Some(defaultness_doc) => defaultness_doc.decoder().decode() - } -} - -fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option { - reader::maybe_get_doc(d, item_tag::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 { - let mut dcx = d.get(item_tag::parent_item).decoder(); +fn entry_data(doc: rbml::Doc, cdata: Cmd) -> EntryData { + let mut dcx = doc.get(item_tag::data).decoder(); dcx.cdata = Some(cdata); + dcx.decode() } -fn item_def_id(d: rbml::Doc, cdata: Cmd) -> DefId { - DefId { - krate: cdata.cnum, - index: d.get(item_tag::def_index).decoder().decode() - } +fn entry_typed_data<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) + -> EntryTypedData<'tcx> { + let mut dcx = doc.get(item_tag::typed_data).decoder(); + dcx.cdata = Some(cdata); + dcx.tcx = Some(tcx); + + dcx.decode() +} + +fn item_parent_item(cdata: Cmd, d: rbml::Doc) -> Option { + item_def_key(d).parent.map(|index| cdata.local_def_id(index)) } fn doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) -> Ty<'tcx> { @@ -404,53 +390,63 @@ fn maybe_doc_type<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: }) } -fn doc_trait_ref<'a, 'tcx>(doc: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>, cdata: Cmd) - -> ty::TraitRef<'tcx> { - let mut dcx = doc.decoder(); - dcx.tcx = Some(tcx); - dcx.cdata = Some(cdata); - dcx.decode() -} - fn item_name(item: rbml::Doc) -> ast::Name { maybe_item_name(item).expect("no item in item_name") } fn maybe_item_name(item: rbml::Doc) -> Option { - reader::maybe_get_doc(item, item_tag::name).map(|name| { - name.decoder().decode() - }) + let name = match item_def_key(item).disambiguated_data.data { + DefPathData::TypeNs(name) | + DefPathData::ValueNs(name) | + DefPathData::Module(name) | + DefPathData::MacroDef(name) | + DefPathData::TypeParam(name) | + DefPathData::LifetimeDef(name) | + DefPathData::EnumVariant(name) | + DefPathData::Field(name) | + DefPathData::Binding(name) => Some(name), + + DefPathData::InlinedRoot(_) => bug!("unexpected DefPathData"), + + DefPathData::CrateRoot | + DefPathData::Misc | + DefPathData::Impl | + DefPathData::ClosureExpr | + DefPathData::StructCtor | + DefPathData::Initializer | + DefPathData::ImplTrait => None + }; + + name.map(|s| token::intern(&s)) } -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) - } - Family::Mod => Def::Mod(did), - Family::ForeignMod => Def::ForeignMod(did), - Family::Variant(..) => { - Def::Variant(item_require_parent_item(cdata, item), did) - } - Family::Trait => Def::Trait(did), - Family::Enum => Def::Enum(did), +impl Family { + fn to_def(&self, did: DefId) -> Option { + Some(match *self { + Family::Const => Def::Const(did), + Family::AssociatedConst => Def::AssociatedConst(did), + Family::ImmStatic | Family::ForeignImmStatic => Def::Static(did, false), + Family::MutStatic | Family::ForeignMutStatic => Def::Static(did, true), + Family::Struct => Def::Struct(did), + Family::Union => Def::Union(did), + Family::Fn | Family::ForeignFn => Def::Fn(did), + Family::Method => Def::Method(did), + Family::Type => Def::TyAlias(did), + Family::AssociatedType => Def::AssociatedTy(did), + Family::Mod => Def::Mod(did), + Family::Variant => Def::Variant(did), + Family::Trait => Def::Trait(did), + Family::Enum => Def::Enum(did), - Family::Impl | - Family::DefaultImpl | - Family::PublicField | - Family::InheritedField => { - return None - } - }) + Family::ForeignMod | + Family::Impl | + Family::DefaultImpl | + Family::Field | + Family::Closure => { + return None + } + }) + } } pub fn get_trait_def<'a, 'tcx>(cdata: Cmd, @@ -459,13 +455,46 @@ 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 = item_doc.get(item_tag::unsafety).decoder().decode(); - let paren_sugar = item_doc.get(item_tag::paren_sugar).decoder().decode(); - let trait_ref = doc_trait_ref(item_doc.get(item_tag::trait_ref), tcx, cdata); - let def_path = def_path(cdata, item_id).unwrap(); - ty::TraitDef::new(unsafety, paren_sugar, generics, trait_ref, - def_path.deterministic_hash(tcx)) + let data = match entry_data(item_doc, cdata) { + EntryData::Trait(data) => data, + _ => bug!() + }; + let typed_data = match entry_typed_data(item_doc, tcx, cdata) { + EntryTypedData::Trait(data) => data, + _ => bug!() + }; + + ty::TraitDef::new(data.unsafety, data.paren_sugar, generics, typed_data.trait_ref, + def_path(cdata, item_id).unwrap().deterministic_hash(tcx))) +} + +fn get_variant<'tcx>(cdata: Cmd, + item: rbml::Doc, + index: DefIndex) + -> (ty::VariantDefData<'tcx, 'tcx>, Option) { + let data = match entry_data(item, cdata) { + EntryData::Variant(data) => data, + _ => bug!() + }; + + let mut dcx = item.get(item_tag::children).decoder(); + dcx.cdata = Some(cdata); + + let fields = dcx.seq().map(|index| { + let f = cdata.lookup_item(index); + ty::FieldDefData::new(cdata.local_def_id(index), + item_name(f), + item_visibility(f)) + }).collect(); + + (ty::VariantDefData { + did: cdata.local_def_id(data.struct_ctor.unwrap_or(index)), + name: item_name(item), + fields: fields, + disr_val: ConstInt::Infer(data.disr), + kind: data.kind, + }, data.struct_ctor) } pub fn get_adt_def<'a, 'tcx>(cdata: Cmd, @@ -473,116 +502,47 @@ pub fn get_adt_def<'a, 'tcx>(cdata: Cmd, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::AdtDefMaster<'tcx> { - fn expect_variant_kind(family: Family) -> ty::VariantKind { - 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> { + let doc = cdata.lookup_item(item_id); + let did = cdata.local_def_id(item_id); + let mut ctor_index = None; + let family = item_family(doc); + let variants = if family == Family::Enum { let mut dcx = doc.get(item_tag::children).decoder(); dcx.cdata = Some(cdata); - dcx.seq().map(|did: DefId| { - let item = cdata.lookup_item(did.index); - let disr = item.get(item_tag::disr_val).decoder().decode(); - ty::VariantDefData { - did: did, - name: item_name(item), - fields: get_variant_fields(cdata, item), - disr_val: ConstInt::Infer(disr), - kind: expect_variant_kind(item_family(item)), - } + dcx.seq().map(|index| { + let (variant, struct_ctor) = get_variant(cdata, cdata.lookup_item(index), index); + assert_eq!(struct_ctor, None); + variant }).collect() - } - fn get_variant_fields<'tcx>(cdata: Cmd, doc: rbml::Doc) -> Vec> { - let mut dcx = doc.get(item_tag::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(did, item_name(f), vis) - }).collect() - } - fn get_struct_variant<'tcx>(cdata: Cmd, - doc: rbml::Doc, - did: DefId) -> ty::VariantDefData<'tcx, 'tcx> { - ty::VariantDefData { - did: did, - name: item_name(doc), - fields: get_variant_fields(cdata, doc), - disr_val: ConstInt::Infer(0), - kind: expect_variant_kind(item_family(doc)), - } - } - - let doc = cdata.lookup_item(item_id); - let did = DefId { krate: cdata.cnum, index: item_id }; - let mut ctor_did = None; - let (kind, variants) = match item_family(doc) { - Enum => { - (AdtKind::Enum, get_enum_variants(cdata, doc)) - } - Struct(..) => { - // Use separate constructor id for unit/tuple structs and reuse did for braced structs. - ctor_did = reader::maybe_get_doc(doc, item_tag::struct_ctor).map(|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))]) - } - Union => { - (AdtKind::Union, vec![get_struct_variant(cdata, doc, did)]) - } - _ => bug!("get_adt_def called on a non-ADT {:?} - {:?}", item_family(doc), did) + } else{ + let (variant, struct_ctor) = get_variant(cdata, doc, item_id); + ctor_index = struct_ctor; + vec![variant] + }; + let kind = match family { + Family::Enum => ty::AdtKind::Enum, + Family::Struct => ty::AdtKind::Struct, + Family::Union => ty::AdtKind::Union, + _ => bug!("get_adt_def called on a non-ADT {:?} - {:?}", + family, did) }; let adt = tcx.intern_adt_def(did, kind, variants); - if let Some(ctor_did) = ctor_did { + if let Some(ctor_index) = ctor_index { // Make adt definition available through constructor id as well. - tcx.insert_adt_def(ctor_did, adt); + tcx.insert_adt_def(cdata.local_def_id(ctor_index), adt); } // this needs to be done *after* the variant is interned, // to support recursive structures for variant in &adt.variants { - if variant.kind == ty::VariantKind::Tuple && adt.is_enum() { - // tuple-like enum variant fields aren't real items - get the types - // from the ctor. - debug!("evaluating the ctor-type of {:?}", - variant.name); - let ctor_ty = get_type(cdata, variant.did.index, tcx); - debug!("evaluating the ctor-type of {:?}.. {:?}", - variant.name, - ctor_ty); - let field_tys = match ctor_ty.sty { - ty::TyFnDef(.., &ty::BareFnTy { sig: ty::Binder(ty::FnSig { - ref inputs, .. - }), ..}) => { - // tuple-struct constructors don't have escaping regions - assert!(!inputs.has_escaping_regions()); - inputs - }, - _ => bug!("tuple-variant ctor is not an ADT") - }; - for (field, &ty) in variant.fields.iter().zip(field_tys.iter()) { - field.fulfill_ty(ty); - } - } else { - for field in &variant.fields { - debug!("evaluating the type of {:?}::{:?}", variant.name, field.name); - let ty = get_type(cdata, field.did.index, tcx); - field.fulfill_ty(ty); - debug!("evaluating the type of {:?}::{:?}: {:?}", - variant.name, field.name, ty); - } + for field in &variant.fields { + debug!("evaluating the type of {:?}::{:?}", variant.name, field.name); + let ty = get_type(cdata, field.did.index, tcx); + field.fulfill_ty(ty); + debug!("evaluating the type of {:?}::{:?}: {:?}", + variant.name, field.name, ty); } } @@ -641,24 +601,19 @@ pub fn get_visibility(cdata: Cmd, id: DefIndex) -> ty::Visibility { item_visibility(cdata.lookup_item(id)) } -pub fn get_parent_impl(cdata: Cmd, id: DefIndex) -> Option { - let item = cdata.lookup_item(id); - reader::maybe_get_doc(item, item_tag::parent_impl).map(|doc| { - let mut dcx = doc.decoder(); - dcx.cdata = Some(cdata); - dcx.decode() - }) +fn get_impl_data(cdata: Cmd, id: DefIndex) -> ImplData { + match entry_data(cdata.lookup_item(id), cdata) { + EntryData::Impl(data) => data, + _ => bug!() + } } -pub fn get_repr_attrs(cdata: Cmd, id: DefIndex) -> Vec { - let item = cdata.lookup_item(id); - reader::maybe_get_doc(item, item_tag::repr).map_or(vec![], |doc| { - doc.decoder().decode() - }) +pub fn get_parent_impl(cdata: Cmd, id: DefIndex) -> Option { + get_impl_data(cdata, id).parent_impl } pub fn get_impl_polarity(cdata: Cmd, id: DefIndex) -> hir::ImplPolarity { - cdata.lookup_item(id).get(item_tag::polarity).decoder().decode() + get_impl_data(cdata, id).polarity } pub fn get_custom_coerce_unsized_kind( @@ -666,10 +621,7 @@ pub fn get_custom_coerce_unsized_kind( id: DefIndex) -> Option { - let item_doc = cdata.lookup_item(id); - reader::maybe_get_doc(item_doc, item_tag::impl_coerce_unsized_kind).map(|kind_doc| { - kind_doc.decoder().decode() - }) + get_impl_data(cdata, id).coerce_unsized_kind } pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd, @@ -677,10 +629,10 @@ pub fn get_impl_trait<'a, 'tcx>(cdata: Cmd, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option> { - let item_doc = cdata.lookup_item(id); - reader::maybe_get_doc(item_doc, item_tag::trait_ref).map(|tp| { - doc_trait_ref(tp, tcx, cdata) - }) + match entry_typed_data(cdata.lookup_item(id), tcx, cdata) { + EntryTypedData::Impl(data) => data.trait_ref, + _ => bug!() + } } /// Iterates over the language items in the given crate. @@ -691,8 +643,8 @@ pub fn get_lang_items(cdata: Cmd) -> Vec<(DefIndex, usize)> { /// 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) + mut get_crate_data: &mut G, + mut callback: &mut F) where F: FnMut(Def, ast::Name, ty::Visibility), G: FnMut(CrateNum) -> Rc, { @@ -709,31 +661,24 @@ pub fn each_child_of_item(cdata: Cmd, id: DefIndex, 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 { - None - } else { - Some(get_crate_data(child_def_id.krate)) - }; - let crate_data = match crate_data { - Some(ref cdata) => &**cdata, - None => cdata - }; - + for child_index in dcx.seq::() { // Get the item. - if let Some(child_item_doc) = crate_data.get_item(child_def_id.index) { + if let Some(child) = cdata.get_item(child_index) { // Hand off the item to the callback. - 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); + let family = item_family(child); + if let Family::ForeignMod = family { + each_child_of_item(cdata, child_index, get_crate_data, callback); + } else if let Some(def) = family.to_def(cdata.local_def_id(child_index)) { + callback(def, item_name(child), item_visibility(child)); } } } - for exp in dcx.seq_mut::() { + let reexports = match entry_data(item_doc, cdata) { + EntryData::Mod(data) => data.reexports, + _ => return + }; + for exp in reexports { // This reexport may be in yet another crate. let crate_data = if exp.def_id.krate == cdata.cnum { None @@ -746,9 +691,9 @@ pub fn each_child_of_item(cdata: Cmd, id: DefIndex, }; // Get the item. - if let Some(child_item_doc) = crate_data.get_item(exp.def_id.index) { + if let Some(child) = crate_data.get_item(exp.def_id.index) { // Hand off the item to the callback. - if let Some(def) = item_to_def(crate_data, child_item_doc, exp.def_id) { + if let Some(def) = item_family(child).to_def(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); @@ -757,62 +702,21 @@ pub fn each_child_of_item(cdata: Cmd, id: DefIndex, } } -pub fn get_item_name(cdata: Cmd, id: DefIndex) -> ast::Name { - item_name(cdata.lookup_item(id)) -} - pub fn maybe_get_item_name(cdata: Cmd, id: DefIndex) -> Option { maybe_item_name(cdata.lookup_item(id)) } -pub enum FoundAst<'ast> { - Found(&'ast InlinedItem), - FoundParent(DefId, &'ast hir::Item), - NotFound, -} - pub fn maybe_get_item_ast<'a, 'tcx>(cdata: Cmd, tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefIndex) - -> FoundAst<'tcx> { + -> Option<&'tcx InlinedItem> { debug!("Looking up item: {:?}", id); let item_doc = cdata.lookup_item(id); - let item_did = item_def_id(item_doc, cdata); - let parent_def_id = DefId { - krate: cdata.cnum, - index: def_key(cdata, id).parent.unwrap() - }; + let item_did = cdata.local_def_id(id); + let parent_def_id = cdata.local_def_id(def_key(cdata, id).parent.unwrap()); let mut parent_def_path = def_path(cdata, id).unwrap(); parent_def_path.data.pop(); - if let Some(ast_doc) = reader::maybe_get_doc(item_doc, item_tag::ast as usize) { - let ii = decode_inlined_item(cdata, - tcx, - parent_def_path, - parent_def_id, - ast_doc, - item_did); - return FoundAst::Found(ii); - } else if let Some(parent_did) = item_parent_item(cdata, item_doc) { - // Remove the last element from the paths, since we are now - // trying to inline the parent. - let grandparent_def_id = DefId { - krate: cdata.cnum, - index: def_key(cdata, parent_def_id.index).parent.unwrap() - }; - let mut grandparent_def_path = parent_def_path; - grandparent_def_path.data.pop(); - let parent_doc = cdata.lookup_item(parent_did.index); - if let Some(ast_doc) = reader::maybe_get_doc(parent_doc, item_tag::ast as usize) { - let ii = decode_inlined_item(cdata, - tcx, - grandparent_def_path, - grandparent_def_id, - ast_doc, - parent_did); - if let &InlinedItem::Item(_, ref i) = ii { - return FoundAst::FoundParent(parent_did, i); - } - } - } - FoundAst::NotFound + reader::maybe_get_doc(item_doc, item_tag::ast).map(|ast_doc| { + decode_inlined_item(cdata, tcx, parent_def_path, parent_def_id, ast_doc, item_did) + }) } pub fn is_item_mir_available<'tcx>(cdata: Cmd, id: DefIndex) -> bool { @@ -837,41 +741,41 @@ pub fn maybe_get_item_mir<'a, 'tcx>(cdata: Cmd, }) } -fn get_explicit_self<'a, 'tcx>(cdata: Cmd, item: rbml::Doc, tcx: TyCtxt<'a, 'tcx, 'tcx>) - -> ty::ExplicitSelfCategory<'tcx> { - let mut dcx = item.get(item_tag::trait_method_explicit_self).decoder(); - dcx.cdata = Some(cdata); - dcx.tcx = Some(tcx); - - dcx.decode() -} - -pub fn get_trait_name(cdata: Cmd, id: DefIndex) -> ast::Name { - let doc = cdata.lookup_item(id); - item_name(doc) -} - pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> Option> { let item_doc = cdata.lookup_item(id); + let family = item_family(item_doc); - let def_id = item_def_id(item_doc, cdata); + match family { + Family::AssociatedConst | + Family::Method | + Family::AssociatedType => {} - let container_id = if let Some(id) = item_parent_item(cdata, item_doc) { - id - } else { - return None; - }; + _ => return None + } + + let def_id = cdata.local_def_id(id); + + let container_id = item_parent_item(cdata, item_doc).unwrap(); let container = match item_family(cdata.lookup_item(container_id.index)) { - Trait => TraitContainer(container_id), + Family::Trait => TraitContainer(container_id), _ => ImplContainer(container_id), }; let name = item_name(item_doc); let vis = item_visibility(item_doc); - let defaultness = item_defaultness(item_doc); - Some(match item_family(item_doc) { + let (defaultness, has_body) = match entry_data(item_doc, cdata) { + EntryData::TraitAssociated(data) => { + (hir::Defaultness::Default, data.has_default) + } + EntryData::ImplAssociated(data) => { + (data.defaultness, true) + } + _ => bug!() + }; + + Some(match family { Family::AssociatedConst => { let ty = doc_type(item_doc, tcx, cdata); ty::ConstTraitItem(Rc::new(ty::AssociatedConst { @@ -881,7 +785,7 @@ 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: item_doc.get(item_tag::trait_item_has_body).decoder().decode(), + has_value: has_body, })) } Family::Method => { @@ -894,8 +798,11 @@ 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(cdata, item_doc, tcx); + let explicit_self = match entry_typed_data(item_doc, tcx, cdata) { + EntryTypedData::Method(data) => data.explicit_self, + _ => bug!() + }; ty::MethodTraitItem(Rc::new(ty::Method { name: name, generics: generics, @@ -904,7 +811,7 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a explicit_self: explicit_self, vis: vis, defaultness: defaultness, - has_body: item_doc.get(item_tag::trait_item_has_body).decoder().decode(), + has_body: has_body, def_id: def_id, container: container, })) @@ -920,7 +827,7 @@ pub fn get_impl_or_trait_item<'a, 'tcx>(cdata: Cmd, id: DefIndex, tcx: TyCtxt<'a container: container, })) } - _ => return None + _ => bug!() }) } @@ -931,49 +838,33 @@ pub fn get_item_variances(cdata: Cmd, id: DefIndex) -> Vec { 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, item_tag::struct_ctor).map(|ctor_doc| { - let mut dcx = ctor_doc.decoder(); - dcx.cdata = Some(cdata); - dcx.decode() - }) -} + let data = match entry_data(cdata.lookup_item(node_id), cdata) { + EntryData::Variant(data) => data, + _ => bug!() + }; -/// If node_id is the constructor of a tuple struct, retrieve the NodeId of -/// the actual type definition, otherwise, return None -pub fn get_tuple_struct_definition_if_ctor(cdata: Cmd, - node_id: DefIndex) - -> Option -{ - let item = cdata.lookup_item(node_id); - reader::maybe_get_doc(item, item_tag::is_tuple_struct_ctor).and_then(|doc| { - if doc.decoder().decode() { - Some(item_require_parent_item(cdata, item)) - } else { - None - } - }) + data.struct_ctor.map(|index| cdata.local_def_id(index)) } pub fn get_item_attrs(cdata: Cmd, - orig_node_id: DefIndex) + node_id: DefIndex) -> Vec { // The attributes for a tuple struct are attached to the definition, not the ctor; // we assume that someone passing in a tuple struct ctor is actually wanting to // look at the definition - let node_id = get_tuple_struct_definition_if_ctor(cdata, orig_node_id); - let node_id = node_id.map(|x| x.index).unwrap_or(orig_node_id); - let item = cdata.lookup_item(node_id); + let mut item = cdata.lookup_item(node_id); + let def_key = item_def_key(item); + if def_key.disambiguated_data.data == DefPathData::StructCtor { + item = cdata.lookup_item(def_key.parent.unwrap()); + } get_attributes(item) } pub fn get_struct_field_names(cdata: Cmd, id: DefIndex) -> Vec { - let mut dcx = cdata.lookup_item(id).get(item_tag::fields).decoder(); + let mut dcx = cdata.lookup_item(id).get(item_tag::children).decoder(); dcx.cdata = Some(cdata); - dcx.seq().map(|did: DefId| { - item_name(cdata.lookup_item(did.index)) - }).collect() + dcx.seq().map(|index| item_name(cdata.lookup_item(index))).collect() } fn get_attributes(md: rbml::Doc) -> Vec { @@ -1019,36 +910,8 @@ fn list_crate_deps(data: &[u8], out: &mut io::Write) -> io::Result<()> { Ok(()) } -pub fn maybe_get_crate_hash(data: &[u8]) -> Option { - let cratedoc = rbml::Doc::new(data); - reader::maybe_get_doc(cratedoc, root_tag::crate_hash).map(|doc| { - doc.decoder().decode() - }) -} - -pub fn get_crate_hash(data: &[u8]) -> Svh { - rbml::Doc::new(data).get(root_tag::crate_hash).decoder().decode() -} - -pub fn maybe_get_crate_name(data: &[u8]) -> Option { - let cratedoc = rbml::Doc::new(data); - reader::maybe_get_doc(cratedoc, root_tag::crate_crate_name).map(|doc| { - doc.decoder().decode() - }) -} - -pub fn get_crate_disambiguator(data: &[u8]) -> String { - rbml::Doc::new(data).get(root_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, root_tag::crate_triple); - triple_doc.map(|s| s.decoder().decode()) -} - -pub fn get_crate_name(data: &[u8]) -> String { - maybe_get_crate_name(data).expect("no crate name in crate") +pub fn get_crate_info(data: &[u8]) -> CrateInfo { + rbml::Doc::new(data).get(root_tag::crate_info).decoder().decode() } pub fn list_crate_metadata(bytes: &[u8], out: &mut io::Write) -> io::Result<()> { @@ -1118,9 +981,8 @@ pub fn get_trait_of_item(cdata: Cmd, id: DefIndex) -> Option { None => return None, Some(item_id) => item_id, }; - let parent_item_doc = cdata.lookup_item(parent_item_id.index); - match item_family(parent_item_doc) { - Trait => Some(item_def_id(parent_item_doc, cdata)), + match item_family(cdata.lookup_item(parent_item_id.index)) { + Family::Trait => Some(parent_item_id), _ => None } } @@ -1131,11 +993,6 @@ pub fn get_native_libraries(cdata: Cmd) rbml::Doc::new(cdata.data()).get(root_tag::native_libraries).decoder().decode() } -pub fn get_plugin_registrar_fn(data: &[u8]) -> Option { - reader::maybe_get_doc(rbml::Doc::new(data), root_tag::plugin_registrar_fn) - .map(|doc| doc.decoder().decode()) -} - pub fn each_exported_macro(data: &[u8], mut f: F) where F: FnMut(ast::Name, Vec, Span, String) -> bool, { @@ -1147,11 +1004,6 @@ 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), root_tag::macro_derive_registrar) - .map(|doc| doc.decoder().decode()) -} - pub fn get_dylib_dependency_formats(cdata: Cmd) -> Vec<(CrateNum, LinkagePreference)> { @@ -1167,9 +1019,9 @@ pub fn get_missing_lang_items(cdata: Cmd) -> Vec { rbml::Doc::new(cdata.data()).get(root_tag::lang_items_missing).decoder().decode() } -pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec { +pub fn get_fn_arg_names(cdata: Cmd, id: DefIndex) -> Vec { let method_doc = cdata.lookup_item(id); - match reader::maybe_get_doc(method_doc, item_tag::method_argument_names) { + match reader::maybe_get_doc(method_doc, item_tag::fn_arg_names) { Some(args_doc) => args_doc.decoder().decode(), None => vec![], } @@ -1178,24 +1030,16 @@ pub fn get_method_arg_names(cdata: Cmd, id: DefIndex) -> Vec { pub fn get_reachable_ids(cdata: Cmd) -> Vec { let dcx = rbml::Doc::new(cdata.data()).get(root_tag::reachable_ids).decoder(); - dcx.seq().map(|index| { - DefId { - krate: cdata.cnum, - index: index, - } - }).collect() + dcx.seq().map(|index| cdata.local_def_id(index)).collect() } pub fn is_const_fn(cdata: Cmd, id: DefIndex) -> bool { - match reader::maybe_get_doc(cdata.lookup_item(id), item_tag::constness) { - None => false, - Some(doc) => { - match doc.decoder().decode() { - hir::Constness::Const => true, - hir::Constness::NotConst => false, - } - } - } + let constness = match entry_data(cdata.lookup_item(id), cdata) { + EntryData::ImplAssociated(data) => data.constness, + EntryData::Fn(data) => data.constness, + _ => hir::Constness::NotConst + }; + constness == hir::Constness::Const } pub fn is_extern_item<'a, 'tcx>(cdata: Cmd, @@ -1207,8 +1051,15 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd, None => return false, }; let applicable = match item_family(item_doc) { - ImmStatic | MutStatic => true, - Fn => get_generics(cdata, id, tcx).types.is_empty(), + Family::ImmStatic | + Family::MutStatic | + Family::ForeignImmStatic | + Family::ForeignMutStatic => true, + + Family::Fn | Family::ForeignFn => { + get_generics(cdata, id, tcx).types.is_empty() + } + _ => false, }; @@ -1221,13 +1072,12 @@ pub fn is_extern_item<'a, 'tcx>(cdata: Cmd, } pub fn is_foreign_item(cdata: Cmd, id: DefIndex) -> bool { - let item_doc = cdata.lookup_item(id); - let parent_item_id = match item_parent_item(cdata, item_doc) { - None => return false, - Some(item_id) => item_id, - }; - let parent_item_doc = cdata.lookup_item(parent_item_id.index); - item_family(parent_item_doc) == ForeignMod + match item_family(cdata.lookup_item(id)) { + Family::ForeignImmStatic | + Family::ForeignMutStatic | + Family::ForeignFn => true, + _ => false + } } fn doc_generics<'a, 'tcx>(base_doc: rbml::Doc, @@ -1268,7 +1118,10 @@ fn doc_predicates<'a, 'tcx>(base_doc: rbml::Doc, } pub fn is_defaulted_trait(cdata: Cmd, trait_id: DefIndex) -> bool { - cdata.lookup_item(trait_id).get(item_tag::defaulted_trait).decoder().decode() + match entry_data(cdata.lookup_item(trait_id), cdata) { + EntryData::Trait(data) => data.has_default_impl, + _ => bug!() + } } pub fn is_default_impl(cdata: Cmd, impl_id: DefIndex) -> bool { @@ -1280,29 +1133,27 @@ pub fn get_imported_filemaps(metadata: &[u8]) -> Vec { } pub fn closure_kind(cdata: Cmd, closure_id: DefIndex) -> ty::ClosureKind { - cdata.lookup_item(closure_id).get(item_tag::closure_kind).decoder().decode() + match entry_data(cdata.lookup_item(closure_id), cdata) { + EntryData::Closure(data) => data.kind, + _ => bug!() + } } 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 = closure_doc.get(item_tag::closure_ty); - let mut dcx = closure_ty_doc.decoder(); - dcx.tcx = Some(tcx); - dcx.cdata = Some(cdata); - dcx.decode() + match entry_typed_data(cdata.lookup_item(closure_id), tcx, cdata) { + EntryTypedData::Closure(data) => data.ty, + _ => bug!() + } } pub fn def_key(cdata: Cmd, id: DefIndex) -> hir_map::DefKey { debug!("def_key: id={:?}", id); - let item_doc = cdata.lookup_item(id); - item_def_key(item_doc) + item_def_key(cdata.lookup_item(id)) } fn item_def_key(item_doc: rbml::Doc) -> hir_map::DefKey { - let simple_key = item_doc.get(item_tag::def_key).decoder().decode(); - let name = maybe_item_name(item_doc).map(|name| name.as_str()); - def_key::recover_def_key(simple_key, name) + item_doc.get(item_tag::def_key).decoder().decode() } // Returns the path leading to the thing with this `id`. Note that @@ -1316,7 +1167,3 @@ pub fn def_path(cdata: Cmd, id: DefIndex) -> Option { None } } - -pub fn get_panic_strategy(data: &[u8]) -> PanicStrategy { - rbml::Doc::new(data).get(root_tag::panic_strategy).decoder().decode() -} diff --git a/src/librustc_metadata/def_key.rs b/src/librustc_metadata/def_key.rs deleted file mode 100644 index 285ca2e4d4d..00000000000 --- a/src/librustc_metadata/def_key.rs +++ /dev/null @@ -1,110 +0,0 @@ -// Copyright 2016 The Rust Project Developers. See the COPYRIGHT -// file at the top-level directory of this distribution and at -// http://rust-lang.org/COPYRIGHT. -// -// Licensed under the Apache License, Version 2.0 or the MIT license -// , at your -// option. This file may not be copied, modified, or distributed -// except according to those terms. - -use rustc::hir::def_id::DefIndex; -use rustc::hir::map as hir_map; -use syntax::parse::token::InternedString; - -#[derive(RustcEncodable, RustcDecodable)] -pub struct DefKey { - pub parent: Option, - pub disambiguated_data: DisambiguatedDefPathData, -} - -#[derive(RustcEncodable, RustcDecodable)] -pub struct DisambiguatedDefPathData { - pub data: DefPathData, - pub disambiguator: u32, -} - -#[derive(RustcEncodable, RustcDecodable)] -pub enum DefPathData { - CrateRoot, - Misc, - Impl, - TypeNs, - ValueNs, - Module, - MacroDef, - ClosureExpr, - TypeParam, - LifetimeDef, - EnumVariant, - Field, - StructCtor, - Initializer, - Binding, - ImplTrait, -} - -pub fn simplify_def_key(key: hir_map::DefKey) -> DefKey { - let data = DisambiguatedDefPathData { - data: simplify_def_path_data(key.disambiguated_data.data), - disambiguator: key.disambiguated_data.disambiguator, - }; - DefKey { - parent: key.parent, - disambiguated_data: data, - } -} - -fn simplify_def_path_data(data: hir_map::DefPathData) -> DefPathData { - match data { - hir_map::DefPathData::CrateRoot => DefPathData::CrateRoot, - hir_map::DefPathData::InlinedRoot(_) => bug!("unexpected DefPathData"), - hir_map::DefPathData::Misc => DefPathData::Misc, - hir_map::DefPathData::Impl => DefPathData::Impl, - hir_map::DefPathData::TypeNs(_) => DefPathData::TypeNs, - hir_map::DefPathData::ValueNs(_) => DefPathData::ValueNs, - hir_map::DefPathData::Module(_) => DefPathData::Module, - hir_map::DefPathData::MacroDef(_) => DefPathData::MacroDef, - hir_map::DefPathData::ClosureExpr => DefPathData::ClosureExpr, - hir_map::DefPathData::TypeParam(_) => DefPathData::TypeParam, - hir_map::DefPathData::LifetimeDef(_) => DefPathData::LifetimeDef, - hir_map::DefPathData::EnumVariant(_) => DefPathData::EnumVariant, - hir_map::DefPathData::Field(_) => DefPathData::Field, - hir_map::DefPathData::StructCtor => DefPathData::StructCtor, - hir_map::DefPathData::Initializer => DefPathData::Initializer, - hir_map::DefPathData::Binding(_) => DefPathData::Binding, - hir_map::DefPathData::ImplTrait => DefPathData::ImplTrait, - } -} - -pub fn recover_def_key(key: DefKey, name: Option) -> hir_map::DefKey { - let data = hir_map::DisambiguatedDefPathData { - data: recover_def_path_data(key.disambiguated_data.data, name), - disambiguator: key.disambiguated_data.disambiguator, - }; - hir_map::DefKey { - parent: key.parent, - disambiguated_data: data, - } -} - -fn recover_def_path_data(data: DefPathData, name: Option) -> hir_map::DefPathData { - match data { - DefPathData::CrateRoot => hir_map::DefPathData::CrateRoot, - DefPathData::Misc => hir_map::DefPathData::Misc, - DefPathData::Impl => hir_map::DefPathData::Impl, - DefPathData::TypeNs => hir_map::DefPathData::TypeNs(name.unwrap()), - DefPathData::ValueNs => hir_map::DefPathData::ValueNs(name.unwrap()), - DefPathData::Module => hir_map::DefPathData::Module(name.unwrap()), - DefPathData::MacroDef => hir_map::DefPathData::MacroDef(name.unwrap()), - DefPathData::ClosureExpr => hir_map::DefPathData::ClosureExpr, - DefPathData::TypeParam => hir_map::DefPathData::TypeParam(name.unwrap()), - DefPathData::LifetimeDef => hir_map::DefPathData::LifetimeDef(name.unwrap()), - DefPathData::EnumVariant => hir_map::DefPathData::EnumVariant(name.unwrap()), - DefPathData::Field => hir_map::DefPathData::Field(name.unwrap()), - DefPathData::StructCtor => hir_map::DefPathData::StructCtor, - DefPathData::Initializer => hir_map::DefPathData::Initializer, - DefPathData::Binding => hir_map::DefPathData::Binding(name.unwrap()), - DefPathData::ImplTrait => hir_map::DefPathData::ImplTrait, - } -} diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 1e4c61e0b2e..3ad9251b072 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -16,15 +16,12 @@ use astencode::encode_inlined_item; use common::*; use cstore; -use decoder; -use def_key; use index::{self, IndexData}; -use middle::cstore::{InlinedItemRef, LinkMeta, LinkagePreference}; +use rustc::middle::cstore::{InlinedItemRef, LinkMeta, LinkagePreference}; use rustc::hir::def; -use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefId}; -use middle::dependency_format::Linkage; -use rustc::dep_graph::DepNode; +use rustc::hir::def_id::{CrateNum, CRATE_DEF_INDEX, DefIndex, DefId}; +use rustc::middle::dependency_format::Linkage; use rustc::traits::specialization_graph; use rustc::ty::{self, Ty, TyCtxt}; @@ -41,7 +38,7 @@ 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::ast::{self, CRATE_NODE_ID}; use syntax::attr; use syntax; use rbml; @@ -49,7 +46,6 @@ use rbml; use rustc::hir::{self, PatKind}; use rustc::hir::intravisit::Visitor; use rustc::hir::intravisit; -use rustc::hir::map::DefKey; use super::index_builder::{FromId, IndexBuilder, Untracked}; @@ -166,59 +162,29 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { Ok(()) }).unwrap(); } -} -fn encode_name(ecx: &mut EncodeContext, name: Name) { - ecx.start_tag(item_tag::name); - name.encode(ecx).unwrap(); - ecx.end_tag(); -} + /// For every DefId that we create a metadata item for, we include a + /// serialized copy of its DefKey, which allows us to recreate a path. + fn encode_def_key(&mut self, def_id: DefId) { + self.start_tag(item_tag::def_key); + self.tcx.map.def_key(def_id).encode(self); + self.end_tag(); + } -fn encode_def_id(ecx: &mut EncodeContext, def_id: DefId) { - assert!(def_id.is_local()); - ecx.start_tag(item_tag::def_index); - def_id.index.encode(ecx).unwrap(); - ecx.end_tag(); -} + // Item info table encoding + fn encode_family(&mut self, f: Family) { + self.start_tag(item_tag::family); + f.encode(self).unwrap(); + self.end_tag(); + } -fn encode_def_key(ecx: &mut EncodeContext, key: DefKey) { - let simple_key = def_key::simplify_def_key(key); - ecx.start_tag(item_tag::def_key); - simple_key.encode(ecx); - ecx.end_tag(); -} + fn encode_item_variances(&mut self, def_id: DefId) { + let v = self.tcx.item_variances(def_id); + self.start_tag(item_tag::variances); + v.encode(self); + self.end_tag(); + } -/// For every DefId that we create a metadata item for, we include a -/// serialized copy of its DefKey, which allows us to recreate a path. -fn encode_def_id_and_key(ecx: &mut EncodeContext, def_id: DefId) { - encode_def_id(ecx, def_id); - let def_key = ecx.tcx.map.def_key(def_id); - encode_def_key(ecx, def_key); -} - -fn encode_trait_ref<'a, 'tcx>(ecx: &mut EncodeContext<'a, 'tcx>, - trait_ref: ty::TraitRef<'tcx>, - tag: usize) { - ecx.start_tag(tag); - trait_ref.encode(ecx).unwrap(); - ecx.end_tag(); -} - -// Item info table encoding -fn encode_family(ecx: &mut EncodeContext, f: Family) { - ecx.start_tag(item_tag::family); - f.encode(ecx).unwrap(); - ecx.end_tag(); -} - -fn encode_item_variances(ecx: &mut EncodeContext, id: NodeId) { - let v = ecx.tcx.item_variances(ecx.tcx.map.local_def_id(id)); - ecx.start_tag(item_tag::variances); - v.encode(ecx); - ecx.end_tag(); -} - -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), @@ -238,37 +204,21 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.end_tag(); } - fn encode_disr_val(&mut self, - disr_val: ty::Disr) { - self.start_tag(item_tag::disr_val); - disr_val.to_u64_unchecked().encode(self).unwrap(); + fn encode_variant(&mut self, variant: ty::VariantDef, + struct_ctor: Option) + -> EntryData { + self.start_tag(item_tag::children); + self.seq(&variant.fields, |_, f| { + assert!(f.did.is_local()); + f.did.index + }); self.end_tag(); - } - fn encode_parent_item(&mut self, id: DefId) { - self.start_tag(item_tag::parent_item); - id.encode(self).unwrap(); - self.end_tag(); - } - - fn encode_variant_fields(&mut self, - variant: ty::VariantDef) { - self.start_tag(item_tag::fields); - self.seq(&variant.fields, |_, f| f.did); - self.end_tag(); - } -} - -impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { - fn encode_enum_variant_infos(&mut self, enum_did: DefId) { - debug!("encode_enum_variant_info(enum_did={:?})", enum_did); - let def = self.tcx.lookup_adt_def(enum_did); - self.encode_fields(enum_did); - for (i, variant) in def.variants.iter().enumerate() { - self.record(variant.did, - EncodeContext::encode_enum_variant_info, - (enum_did, Untracked(i))); - } + EntryData::Variant(VariantData { + kind: variant.kind, + disr: variant.disr_val.to_u64_unchecked(), + struct_ctor: struct_ctor + }) } } @@ -285,10 +235,8 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let def = tcx.lookup_adt_def(enum_did); let variant = &def.variants[index]; let vid = variant.did; - encode_def_id_and_key(self, vid); - encode_family(self, Family::Variant(variant.kind)); - encode_name(self, variant.name); - self.encode_parent_item(enum_did); + self.encode_def_key(vid); + self.encode_family(Family::Variant); let enum_id = tcx.map.as_local_node_id(enum_did).unwrap(); let enum_vis = &tcx.map.expect_item(enum_id).vis; @@ -296,60 +244,58 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let attrs = tcx.get_attrs(vid); encode_attributes(self, &attrs); - self.encode_repr_attrs(&attrs); + encode_stability(self, vid); - let stab = tcx.lookup_stability(vid); - let depr = tcx.lookup_deprecation(vid); - encode_stability(self, stab); - encode_deprecation(self, depr); + let data = self.encode_variant(variant, None); + + self.start_tag(item_tag::data); + data.encode(self).unwrap(); + self.end_tag(); + + self.start_tag(item_tag::typed_data); + EntryTypedData::Other.encode(self).unwrap(); + self.end_tag(); - self.encode_variant_fields(variant); - self.encode_disr_val(variant.disr_val); self.encode_bounds_and_type_for_item(vid); } } 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)>) { + FromId(id, (md, attrs, vis)): + FromId<(&hir::Mod, &[ast::Attribute], &hir::Visibility)>) { let tcx = self.tcx; - encode_def_id_and_key(self, tcx.map.local_def_id(id)); - encode_family(self, Family::Mod); - encode_name(self, name); + let def_id = tcx.map.local_def_id(id); + self.encode_def_key(def_id); + self.encode_family(Family::Mod); + self.encode_visibility(vis); + encode_stability(self, def_id); + encode_attributes(self, attrs); debug!("(encoding info for module) encoding info for module ID {}", id); // Encode info about all the module children. self.start_tag(item_tag::children); self.seq(&md.item_ids, |_, item_id| { - tcx.map.local_def_id(item_id.id) + tcx.map.local_def_id(item_id.id).index }); - - // 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); + // Encode the reexports of this module, if this module is public. + let reexports = match self.reexports.get(&id) { + Some(exports) if *vis == hir::Public => exports.clone(), + _ => vec![] + }; - let stab = tcx.lookup_stability(tcx.map.local_def_id(id)); - let depr = tcx.lookup_deprecation(tcx.map.local_def_id(id)); - encode_stability(self, stab); - encode_deprecation(self, depr); + self.start_tag(item_tag::data); + EntryData::Mod(ModData { + reexports: reexports + }).encode(self).unwrap(); + self.end_tag(); - encode_attributes(self, attrs); - } - - fn encode_struct_field_family(&mut self, - visibility: ty::Visibility) { - encode_family(self, if visibility.is_public() { - Family::PublicField - } else { - Family::InheritedField - }); + self.start_tag(item_tag::typed_data); + EntryTypedData::Other.encode(self).unwrap(); + self.end_tag(); } fn encode_visibility(&mut self, visibility: T) { @@ -380,18 +326,6 @@ impl HasVisibility for ty::Visibility { } } -fn encode_constness(ecx: &mut EncodeContext, constness: hir::Constness) { - ecx.start_tag(item_tag::constness); - constness.encode(ecx).unwrap(); - ecx.end_tag(); -} - -fn encode_defaultness(ecx: &mut EncodeContext, defaultness: hir::Defaultness) { - ecx.start_tag(item_tag::defaultness); - defaultness.encode(ecx).unwrap(); - ecx.end_tag(); -} - impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { fn encode_fields(&mut self, adt_def_id: DefId) { @@ -424,48 +358,23 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { let nm = field.name; debug!("encode_field: encoding {} {:?}", nm, field.did); - self.encode_struct_field_family(field.vis); - encode_name(self, nm); + self.encode_family(Family::Field); + self.encode_visibility(field.vis); self.encode_bounds_and_type_for_item(field.did); - encode_def_id_and_key(self, field.did); + self.encode_def_key(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); - encode_deprecation(self, depr); + encode_stability(self, field.did); } - fn encode_struct_ctor(&mut self, - (struct_def_id, struct_node_id, ctor_node_id): - (DefId, ast::NodeId, ast::NodeId)) { - let tcx = self.tcx; - let def = tcx.lookup_adt_def(struct_def_id); - let variant = def.struct_variant(); - 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, Family::Struct(variant.kind)); + fn encode_struct_ctor(&mut self, ctor_def_id: DefId) { + self.encode_def_key(ctor_def_id); + self.encode_family(Family::Struct); self.encode_bounds_and_type_for_item(ctor_def_id); - encode_name(self, item.name); - self.encode_parent_item(struct_def_id); - let stab = tcx.lookup_stability(ctor_def_id); - let depr = tcx.lookup_deprecation(ctor_def_id); - encode_stability(self, stab); - encode_deprecation(self, depr); - - // indicate that this is a tuple struct ctor, because - // downstream users will normally want the tuple struct - // definition, but without this there is no way for them - // to tell that they actually have a ctor rather than a - // normal function - self.start_tag(item_tag::is_tuple_struct_ctor); - true.encode(self).unwrap(); - self.end_tag(); + encode_stability(self, ctor_def_id); } fn encode_generics(&mut self, @@ -489,215 +398,137 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.end_tag(); } - fn encode_method_ty_fields(&mut self, method_ty: &ty::Method<'tcx>) { - encode_def_id_and_key(self, method_ty.def_id); - encode_name(self, method_ty.name); - self.encode_generics(&method_ty.generics, &method_ty.predicates); - self.encode_visibility(method_ty.vis); - - self.start_tag(item_tag::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, - (trait_def_id, item_def_id, trait_item): - (DefId, DefId, &hir::TraitItem)) { + fn encode_info_for_trait_item(&mut self, def_id: DefId) { let tcx = self.tcx; - self.encode_parent_item(trait_def_id); + let node_id = tcx.map.as_local_node_id(def_id).unwrap(); + let ast_item = tcx.map.expect_trait_item(node_id); + let trait_item = tcx.impl_or_trait_item(def_id); + let (family, has_default, typed_data) = match trait_item { + ty::ConstTraitItem(ref associated_const) => { + self.encode_bounds_and_type_for_item(def_id); - let stab = tcx.lookup_stability(item_def_id); - let depr = tcx.lookup_deprecation(item_def_id); - encode_stability(self, stab); - encode_deprecation(self, depr); + let trait_def_id = trait_item.container().id(); + encode_inlined_item(self, + InlinedItemRef::TraitItem(trait_def_id, ast_item)); - 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, item_def_id); - self.encode_visibility(associated_const.vis); - - encode_family(self, Family::AssociatedConst); - self.encode_bounds_and_type_for_item(item_def_id); + (Family::AssociatedConst, + associated_const.has_value, + EntryTypedData::Other) } - ty::MethodTraitItem(method_ty) => { - self.encode_method_ty_fields(&method_ty); - 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, item_def_id); - encode_family(self, Family::AssociatedType); + ty::MethodTraitItem(ref method_ty) => { + self.encode_bounds_and_type_for_item(def_id); + (Family::Method, + method_ty.has_body, + EntryTypedData::Method(MethodTypedData { + explicit_self: method_ty.explicit_self + })) + } + ty::TypeTraitItem(ref associated_type) => { if let Some(ty) = associated_type.ty { self.encode_type(ty); } - } - } - encode_attributes(self, &trait_item.attrs); - match trait_item.node { - hir::ConstTraitItem(_, ref default) => { - self.start_tag(item_tag::trait_item_has_body); - default.is_some().encode(self).unwrap(); - self.end_tag(); + (Family::AssociatedType, false, EntryTypedData::Other) + } + }; + + self.encode_def_key(def_id); + self.encode_family(family); + self.encode_visibility(trait_item.vis()); + + encode_stability(self, def_id); + encode_attributes(self, &ast_item.attrs); + if let hir::MethodTraitItem(ref sig, _) = ast_item.node { + self.encode_fn_arg_names(&sig.decl); + }; + + self.start_tag(item_tag::data); + EntryData::TraitAssociated(TraitAssociatedData { + has_default: has_default + }).encode(self).unwrap(); + self.end_tag(); + + self.start_tag(item_tag::typed_data); + typed_data.encode(self).unwrap(); + self.end_tag(); + + self.encode_mir(def_id); + } + + fn encode_info_for_impl_item(&mut self, def_id: DefId) { + let node_id = self.tcx.map.as_local_node_id(def_id).unwrap(); + let ast_item = self.tcx.map.expect_impl_item(node_id); + let impl_item = self.tcx.impl_or_trait_item(def_id); + let impl_def_id = impl_item.container().id(); + let (family, typed_data) = match impl_item { + ty::ConstTraitItem(_) => { + self.encode_bounds_and_type_for_item(def_id); encode_inlined_item(self, - InlinedItemRef::TraitItem(trait_def_id, trait_item)); - self.encode_mir(item_def_id); - } - hir::MethodTraitItem(ref sig, ref body) => { - self.start_tag(item_tag::trait_item_has_body); - body.is_some().encode(self).unwrap(); - self.end_tag(); + InlinedItemRef::ImplItem(impl_def_id, ast_item)); + self.encode_mir(def_id); - self.encode_mir(item_def_id); - self.encode_method_argument_names(&sig.decl); - } - - hir::TypeTraitItem(..) => {} - } - } - - fn encode_info_for_impl_item(&mut self, - (impl_id, impl_item_def_id, ast_item): - (NodeId, DefId, Option<&hir::ImplItem>)) { - match self.tcx.impl_or_trait_item(impl_item_def_id) { - ty::ConstTraitItem(ref associated_const) => { - self.encode_info_for_associated_const(&associated_const, - impl_id, - ast_item) + (Family::AssociatedConst, EntryTypedData::Other) } ty::MethodTraitItem(ref method_type) => { - self.encode_info_for_method(&method_type, - impl_id, - ast_item) + self.encode_bounds_and_type_for_item(def_id); + + (Family::Method, + EntryTypedData::Method(MethodTypedData { + explicit_self: method_type.explicit_self + })) } ty::TypeTraitItem(ref associated_type) => { - self.encode_info_for_associated_type(&associated_type, - impl_id, - ast_item) + if let Some(ty) = associated_type.ty { + self.encode_type(ty); + } + + (Family::AssociatedType, EntryTypedData::Other) } - } - } + }; - fn encode_info_for_associated_const(&mut self, - associated_const: &ty::AssociatedConst, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { - let tcx = self.tcx; - debug!("encode_info_for_associated_const({:?},{:?})", - associated_const.def_id, - associated_const.name); + self.encode_def_key(def_id); + self.encode_family(family); + self.encode_visibility(impl_item.vis()); + encode_attributes(self, &ast_item.attrs); + encode_stability(self, def_id); - 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, Family::AssociatedConst); + let constness = if let hir::ImplItemKind::Method(ref sig, _) = ast_item.node { + if sig.constness == hir::Constness::Const { + encode_inlined_item( + self, + InlinedItemRef::ImplItem(impl_def_id, ast_item)); + } - self.encode_parent_item(tcx.map.local_def_id(parent_id)); + let generics = self.tcx.lookup_generics(def_id); + let types = generics.parent_types as usize + generics.types.len(); + let needs_inline = types > 0 || attr::requests_inline(&ast_item.attrs); + if needs_inline || sig.constness == hir::Constness::Const { + self.encode_mir(def_id); + } + self.encode_fn_arg_names(&sig.decl); + sig.constness + } else { + hir::Constness::NotConst + }; - self.start_tag(item_tag::trait_item_has_body); - true.encode(self).unwrap(); + self.start_tag(item_tag::data); + EntryData::ImplAssociated(ImplAssociatedData { + defaultness: ast_item.defaultness, + constness:constness + }).encode(self).unwrap(); self.end_tag(); - self.encode_bounds_and_type_for_item(associated_const.def_id); - - let stab = tcx.lookup_stability(associated_const.def_id); - let depr = tcx.lookup_deprecation(associated_const.def_id); - encode_stability(self, stab); - encode_deprecation(self, depr); - - if let Some(ii) = impl_item_opt { - encode_attributes(self, &ii.attrs); - encode_defaultness(self, ii.defaultness); - encode_inlined_item(self, - InlinedItemRef::ImplItem(tcx.map.local_def_id(parent_id), - ii)); - self.encode_mir(associated_const.def_id); - } - } - - fn encode_info_for_method(&mut self, - m: &ty::Method<'tcx>, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { - let tcx = self.tcx; - - debug!("encode_info_for_method: {:?} {:?}", m.def_id, - m.name); - self.encode_method_ty_fields(m); - self.encode_parent_item(tcx.map.local_def_id(parent_id)); - - self.start_tag(item_tag::trait_item_has_body); - true.encode(self).unwrap(); + self.start_tag(item_tag::typed_data); + typed_data.encode(self).unwrap(); self.end_tag(); - - let stab = tcx.lookup_stability(m.def_id); - let depr = tcx.lookup_deprecation(m.def_id); - encode_stability(self, stab); - encode_deprecation(self, depr); - - self.encode_bounds_and_type_for_item(m.def_id); - - if let Some(impl_item) = impl_item_opt { - if let hir::ImplItemKind::Method(ref sig, _) = impl_item.node { - 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 || attr::requests_inline(&impl_item.attrs); - if sig.constness == hir::Constness::Const { - encode_inlined_item( - self, - InlinedItemRef::ImplItem(tcx.map.local_def_id(parent_id), - impl_item)); - } - if needs_inline || sig.constness == hir::Constness::Const { - self.encode_mir(m.def_id); - } - encode_constness(self, sig.constness); - encode_defaultness(self, impl_item.defaultness); - self.encode_method_argument_names(&sig.decl); - } - } } - fn encode_info_for_associated_type(&mut self, - associated_type: &ty::AssociatedType<'tcx>, - parent_id: NodeId, - impl_item_opt: Option<&hir::ImplItem>) { - let tcx = self.tcx; - debug!("encode_info_for_associated_type({:?},{:?})", - associated_type.def_id, - associated_type.name); - - 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, Family::AssociatedType); - self.encode_parent_item(tcx.map.local_def_id(parent_id)); - - let stab = tcx.lookup_stability(associated_type.def_id); - let depr = tcx.lookup_deprecation(associated_type.def_id); - encode_stability(self, stab); - encode_deprecation(self, depr); - - if let Some(ii) = impl_item_opt { - encode_attributes(self, &ii.attrs); - encode_defaultness(self, ii.defaultness); - } - - if let Some(ty) = associated_type.ty { - self.encode_type(ty); - } - } - - fn encode_method_argument_names(&mut self, + fn encode_fn_arg_names(&mut self, decl: &hir::FnDecl) { - self.start_tag(item_tag::method_argument_names); + self.start_tag(item_tag::fn_arg_names); self.seq(&decl.inputs, |_, arg| { if let PatKind::Binding(_, ref path1, _) = arg.pat.node { @@ -710,18 +541,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { self.end_tag(); } - fn encode_repr_attrs(&mut self, - attrs: &[ast::Attribute]) { - let mut repr_attrs = Vec::new(); - for attr in attrs { - repr_attrs.extend(attr::find_repr_attrs(self.tcx.sess.diagnostic(), - attr)); - } - self.start_tag(item_tag::repr); - 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(item_tag::mir as usize); @@ -742,16 +561,13 @@ fn encode_inherent_implementations(ecx: &mut EncodeContext, ecx.end_tag(); } -fn encode_stability(ecx: &mut EncodeContext, stab_opt: Option<&attr::Stability>) { - stab_opt.map(|stab| { +fn encode_stability(ecx: &mut EncodeContext, def_id: DefId) { + ecx.tcx.lookup_stability(def_id).map(|stab| { ecx.start_tag(item_tag::stability); stab.encode(ecx).unwrap(); ecx.end_tag(); }); -} - -fn encode_deprecation(ecx: &mut EncodeContext, depr_opt: Option) { - depr_opt.map(|depr| { + ecx.tcx.lookup_deprecation(def_id).map(|depr| { ecx.start_tag(item_tag::deprecation); depr.encode(ecx).unwrap(); ecx.end_tag(); @@ -794,47 +610,26 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("encoding info for item at {}", tcx.sess.codemap().span_to_string(item.span)); - let vis = &item.vis; - - let (stab, depr) = tcx.dep_graph.with_task(DepNode::MetaData(def_id), || { - (tcx.lookup_stability(tcx.map.local_def_id(item.id)), - tcx.lookup_deprecation(tcx.map.local_def_id(item.id))) - }); - - match item.node { + let (family, data, typed_data) = match item.node { hir::ItemStatic(_, m, _) => { - encode_def_id_and_key(self, def_id); - encode_family(self, if m == hir::MutMutable { - Family::MutStatic - } else { - Family::ImmStatic - }); self.encode_bounds_and_type_for_item(def_id); - encode_name(self, item.name); - self.encode_visibility(vis); - encode_stability(self, stab); - encode_deprecation(self, depr); - encode_attributes(self, &item.attrs); + + if m == hir::MutMutable { + (Family::MutStatic, EntryData::Other, EntryTypedData::Other) + } else { + (Family::ImmStatic, EntryData::Other, EntryTypedData::Other) + } } hir::ItemConst(..) => { - encode_def_id_and_key(self, def_id); - encode_family(self, Family::Const); self.encode_bounds_and_type_for_item(def_id); - encode_name(self, item.name); - encode_attributes(self, &item.attrs); encode_inlined_item(self, InlinedItemRef::Item(def_id, item)); self.encode_mir(def_id); - self.encode_visibility(vis); - encode_stability(self, stab); - encode_deprecation(self, depr); + + (Family::Const, EntryData::Other, EntryTypedData::Other) } hir::ItemFn(ref decl, _, constness, _, ref generics, _) => { - encode_def_id_and_key(self, def_id); - 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); - encode_attributes(self, &item.attrs); let needs_inline = tps_len > 0 || attr::requests_inline(&item.attrs); if constness == hir::Constness::Const { encode_inlined_item(self, InlinedItemRef::Item(def_id, item)); @@ -842,224 +637,172 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { if needs_inline || constness == hir::Constness::Const { self.encode_mir(def_id); } - encode_constness(self, constness); - self.encode_visibility(vis); - encode_stability(self, stab); - encode_deprecation(self, depr); - self.encode_method_argument_names(&decl); + self.encode_fn_arg_names(&decl); + + (Family::Fn, EntryData::Fn(FnData { + constness: constness + }), EntryTypedData::Other) } hir::ItemMod(ref m) => { - self.encode_info_for_mod(FromId(item.id, (m, &item.attrs, item.name, &item.vis))); + self.encode_info_for_mod(FromId(item.id, (m, &item.attrs, &item.vis))); + return; } hir::ItemForeignMod(ref fm) => { - encode_def_id_and_key(self, def_id); - encode_family(self, Family::ForeignMod); - encode_name(self, item.name); - // Encode all the items in self module. self.start_tag(item_tag::children); self.seq(&fm.items, |_, foreign_item| { - tcx.map.local_def_id(foreign_item.id) + tcx.map.local_def_id(foreign_item.id).index }); - <[def::Export]>::encode(&[], self).unwrap(); self.end_tag(); - self.encode_visibility(vis); - encode_stability(self, stab); - encode_deprecation(self, depr); + (Family::ForeignMod, EntryData::Other, EntryTypedData::Other) } hir::ItemTy(..) => { - encode_def_id_and_key(self, def_id); - encode_family(self, Family::Type); self.encode_bounds_and_type_for_item(def_id); - encode_name(self, item.name); - self.encode_visibility(vis); - encode_stability(self, stab); - encode_deprecation(self, depr); + + (Family::Type, EntryData::Other, EntryTypedData::Other) } hir::ItemEnum(ref enum_definition, _) => { - encode_def_id_and_key(self, def_id); - encode_family(self, Family::Enum); - encode_item_variances(self, item.id); + self.encode_item_variances(def_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); self.start_tag(item_tag::children); self.seq(&enum_definition.variants, |_, v| { - tcx.map.local_def_id(v.node.data.id()) + tcx.map.local_def_id(v.node.data.id()).index }); - <[def::Export]>::encode(&[], self).unwrap(); self.end_tag(); // Encode inherent implementations for self enumeration. encode_inherent_implementations(self, def_id); - self.encode_visibility(vis); - encode_stability(self, stab); - encode_deprecation(self, depr); + (Family::Enum, EntryData::Other, EntryTypedData::Other) } hir::ItemStruct(ref struct_def, _) => { - /* Index the class*/ let def = tcx.lookup_adt_def(def_id); let variant = def.struct_variant(); - /* Now, make an item for the class itself */ - encode_def_id_and_key(self, def_id); - encode_family(self, Family::Struct(variant.kind)); self.encode_bounds_and_type_for_item(def_id); - encode_item_variances(self, item.id); - encode_name(self, item.name); - encode_attributes(self, &item.attrs); - encode_stability(self, stab); - encode_deprecation(self, depr); - self.encode_visibility(vis); - self.encode_repr_attrs(&item.attrs); + self.encode_item_variances(def_id); /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - self.encode_variant_fields(variant); + let struct_ctor = if !struct_def.is_struct() { + Some(tcx.map.local_def_id(struct_def.id()).index) + } else { + None + }; + let data = self.encode_variant(variant, struct_ctor); // 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.start_tag(item_tag::struct_ctor); - ctor_did.encode(self).unwrap(); - self.end_tag(); - } + (Family::Struct, data, EntryTypedData::Other) } hir::ItemUnion(..) => { - let def = self.tcx.lookup_adt_def(def_id); - let variant = def.struct_variant(); - - encode_def_id_and_key(self, def_id); - encode_family(self, Family::Union); self.encode_bounds_and_type_for_item(def_id); - encode_item_variances(self, item.id); - encode_name(self, item.name); - encode_attributes(self, &item.attrs); - encode_stability(self, stab); - encode_deprecation(self, depr); - self.encode_visibility(vis); - self.encode_repr_attrs(&item.attrs); + self.encode_item_variances(def_id); /* Encode def_ids for each field and method for methods, write all the stuff get_trait_method needs to know*/ - self.encode_variant_fields(variant); - - encode_inlined_item(self, InlinedItemRef::Item(def_id, item)); - self.encode_mir(def_id); + let def = self.tcx.lookup_adt_def(def_id); + let data = self.encode_variant(def.struct_variant(), None); // Encode inherent implementations for self union. encode_inherent_implementations(self, def_id); + + (Family::Union, data, EntryTypedData::Other) } hir::ItemDefaultImpl(..) => { - encode_def_id_and_key(self, def_id); - encode_family(self, Family::DefaultImpl); - encode_name(self, item.name); - - let trait_ref = tcx.impl_trait_ref(tcx.map.local_def_id(item.id)).unwrap(); - encode_trait_ref(self, trait_ref, item_tag::trait_ref); + (Family::DefaultImpl, EntryData::Other, + EntryTypedData::Impl(ImplTypedData { + trait_ref: tcx.impl_trait_ref(def_id) + })) } hir::ItemImpl(_, polarity, ..) => { - encode_def_id_and_key(self, def_id); - encode_family(self, Family::Impl); self.encode_bounds_and_type_for_item(def_id); - encode_name(self, item.name); - encode_attributes(self, &item.attrs); - self.start_tag(item_tag::polarity); - polarity.encode(self).unwrap(); - self.end_tag(); - - match - tcx.custom_coerce_unsized_kinds - .borrow() - .get(&tcx.map.local_def_id(item.id)) - { - Some(&kind) => { - self.start_tag(item_tag::impl_coerce_unsized_kind); - kind.encode(self); - self.end_tag(); - } - None => {} - } + let trait_ref = tcx.impl_trait_ref(def_id); + let parent = if let Some(trait_ref) = trait_ref { + let trait_def = tcx.lookup_trait_def(trait_ref.def_id); + trait_def.ancestors(def_id).skip(1).next().and_then(|node| { + match node { + specialization_graph::Node::Impl(parent) => Some(parent), + _ => None, + } + }) + } else { + None + }; self.start_tag(item_tag::children); - tcx.impl_or_trait_items(def_id).encode(self).unwrap(); - <[def::Export]>::encode(&[], self).unwrap(); + self.seq(&tcx.impl_or_trait_items(def_id)[..], |_, &def_id| { + assert!(def_id.is_local()); + def_id.index + }); self.end_tag(); - let did = tcx.map.local_def_id(item.id); - if let Some(trait_ref) = tcx.impl_trait_ref(did) { - encode_trait_ref(self, trait_ref, item_tag::trait_ref); - - let trait_def = tcx.lookup_trait_def(trait_ref.def_id); - let parent = trait_def.ancestors(did) - .skip(1) - .next() - .and_then(|node| match node { - specialization_graph::Node::Impl(parent) => - Some(parent), - _ => None, - }); - parent.map(|parent| { - self.start_tag(item_tag::parent_impl); - parent.encode(self).unwrap(); - self.end_tag(); - }); - } - encode_stability(self, stab); - encode_deprecation(self, depr); + (Family::Impl, + EntryData::Impl(ImplData { + polarity: polarity, + parent_impl: parent, + coerce_unsized_kind: tcx.custom_coerce_unsized_kinds.borrow() + .get(&def_id).cloned() + }), + EntryTypedData::Impl(ImplTypedData { + trait_ref: trait_ref + })) } hir::ItemTrait(..) => { - encode_def_id_and_key(self, def_id); - encode_family(self, Family::Trait); - encode_item_variances(self, item.id); + self.encode_item_variances(def_id); let trait_def = tcx.lookup_trait_def(def_id); let trait_predicates = tcx.lookup_predicates(def_id); - self.start_tag(item_tag::unsafety); - trait_def.unsafety.encode(self).unwrap(); - self.end_tag(); - - self.start_tag(item_tag::paren_sugar); - trait_def.paren_sugar.encode(self).unwrap(); - self.end_tag(); - - self.start_tag(item_tag::defaulted_trait); - tcx.trait_has_default_impl(def_id).encode(self).unwrap(); - self.end_tag(); - self.encode_generics(&trait_def.generics, &trait_predicates); self.encode_predicates(&tcx.lookup_super_predicates(def_id), item_tag::super_predicates); - encode_trait_ref(self, trait_def.trait_ref, item_tag::trait_ref); - encode_name(self, item.name); - encode_attributes(self, &item.attrs); - self.encode_visibility(vis); - encode_stability(self, stab); - encode_deprecation(self, depr); self.start_tag(item_tag::children); - tcx.impl_or_trait_items(def_id).encode(self).unwrap(); - <[def::Export]>::encode(&[], self).unwrap(); + self.seq(&tcx.impl_or_trait_items(def_id)[..], |_, &def_id| { + assert!(def_id.is_local()); + def_id.index + }); self.end_tag(); // Encode inherent implementations for self trait. encode_inherent_implementations(self, def_id); + + (Family::Trait, + EntryData::Trait(TraitData { + unsafety: trait_def.unsafety, + paren_sugar: trait_def.paren_sugar, + has_default_impl: tcx.trait_has_default_impl(def_id) + }), + EntryTypedData::Trait(TraitTypedData { + trait_ref: trait_def.trait_ref + })) } hir::ItemExternCrate(_) | hir::ItemUse(_) => { bug!("cannot encode info for item {:?}", item) } - } + }; + + self.encode_family(family); + self.encode_def_key(def_id); + self.encode_visibility(&item.vis); + encode_attributes(self, &item.attrs); + encode_stability(self, def_id); + + self.start_tag(item_tag::data); + data.encode(self).unwrap(); + self.end_tag(); + + self.start_tag(item_tag::typed_data); + typed_data.encode(self).unwrap(); + self.end_tag(); } } @@ -1084,88 +827,52 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { // no sub-item recording needed in these cases } hir::ItemEnum(..) => { - self.encode_enum_variant_infos(def_id); + self.encode_fields(def_id); + + let def = self.tcx.lookup_adt_def(def_id); + for (i, variant) in def.variants.iter().enumerate() { + self.record(variant.did, + EncodeContext::encode_enum_variant_info, + (def_id, Untracked(i))); + } } hir::ItemStruct(ref struct_def, _) => { - self.encode_addl_struct_info(def_id, struct_def.id(), item); + self.encode_fields(def_id); + + // If this is a tuple-like struct, encode the type of the constructor. + match self.tcx.lookup_adt_def(def_id).struct_variant().kind { + ty::VariantKind::Struct => { + // no value for structs like struct Foo { ... } + } + ty::VariantKind::Tuple | ty::VariantKind::Unit => { + // there is a value for structs like `struct + // Foo()` and `struct Foo` + let ctor_def_id = self.tcx.map.local_def_id(struct_def.id()); + self.record(ctor_def_id, + EncodeContext::encode_struct_ctor, + ctor_def_id); + } + } } hir::ItemUnion(..) => { - self.encode_addl_union_info(def_id); + self.encode_fields(def_id); } - hir::ItemImpl(.., ref ast_items) => { - self.encode_addl_impl_info(def_id, item.id, ast_items); + hir::ItemImpl(..) => { + for &trait_item_def_id in &self.tcx.impl_or_trait_items(def_id)[..] { + self.record(trait_item_def_id, + EncodeContext::encode_info_for_impl_item, + trait_item_def_id); + } } - hir::ItemTrait(.., ref trait_items) => { - self.encode_addl_trait_info(def_id, trait_items); + hir::ItemTrait(..) => { + for &item_def_id in &self.tcx.impl_or_trait_items(def_id)[..] { + self.record(item_def_id, + EncodeContext::encode_info_for_trait_item, + item_def_id); + } } } } - - fn encode_addl_struct_info(&mut self, - def_id: DefId, - struct_node_id: ast::NodeId, - item: &hir::Item) { - let def = self.tcx.lookup_adt_def(def_id); - let variant = def.struct_variant(); - - self.encode_fields(def_id); - - // If this is a tuple-like struct, encode the type of the constructor. - match variant.kind { - ty::VariantKind::Struct => { - // no value for structs like struct Foo { ... } - } - ty::VariantKind::Tuple | ty::VariantKind::Unit => { - // there is a value for structs like `struct - // Foo()` and `struct Foo` - let ctor_def_id = self.tcx.map.local_def_id(struct_node_id); - self.record(ctor_def_id, - EncodeContext::encode_struct_ctor, - (def_id, item.id, struct_node_id)); - } - } - } - - fn encode_addl_union_info(&mut self, def_id: DefId) { - self.encode_fields(def_id); - } - - fn encode_addl_impl_info(&mut self, - def_id: DefId, - impl_id: ast::NodeId, - ast_items: &[hir::ImplItem]) { - 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 - // appear first in the impl structure, in the same order they do - // in the ast. This is a little sketchy. - let num_implemented_methods = ast_items.len(); - for (i, &trait_item_def_id) in items.iter().enumerate() { - let ast_item = if i < num_implemented_methods { - Some(&ast_items[i]) - } else { - None - }; - - self.record(trait_item_def_id, - EncodeContext::encode_info_for_impl_item, - (impl_id, trait_item_def_id, ast_item)); - } - } - - fn encode_addl_trait_info(&mut self, - def_id: DefId, - trait_items: &[hir::TraitItem]) { - // Now output the trait item info for each trait item. - let r = self.tcx.impl_or_trait_items(def_id); - for (&item_def_id, trait_item) in r.iter().zip(trait_items) { - assert!(item_def_id.is_local()); - self.record(item_def_id, - EncodeContext::encode_info_for_trait_item, - (def_id, item_def_id, trait_item)); - } - } } impl<'a, 'tcx> EncodeContext<'a, 'tcx> { @@ -1175,37 +882,30 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { debug!("writing foreign item {}", tcx.node_path_str(nitem.id)); - encode_def_id_and_key(self, def_id); - let parent_id = tcx.map.get_parent(nitem.id); - self.encode_parent_item(tcx.map.local_def_id(parent_id)); + self.encode_def_key(def_id); self.encode_visibility(&nitem.vis); - match nitem.node { + self.encode_bounds_and_type_for_item(def_id); + let family = match nitem.node { hir::ForeignItemFn(ref fndecl, _) => { - encode_family(self, Family::Fn); - self.encode_bounds_and_type_for_item(def_id); - encode_name(self, nitem.name); - encode_attributes(self, &nitem.attrs); - let stab = tcx.lookup_stability(tcx.map.local_def_id(nitem.id)); - let depr = tcx.lookup_deprecation(tcx.map.local_def_id(nitem.id)); - encode_stability(self, stab); - encode_deprecation(self, depr); - self.encode_method_argument_names(&fndecl); + self.encode_fn_arg_names(&fndecl); + + Family::ForeignFn } - hir::ForeignItemStatic(_, mutbl) => { - encode_family(self, if mutbl { - Family::MutStatic - } else { - 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)); - let depr = tcx.lookup_deprecation(tcx.map.local_def_id(nitem.id)); - encode_stability(self, stab); - encode_deprecation(self, depr); - encode_name(self, nitem.name); - } - } + hir::ForeignItemStatic(_, true) => Family::ForeignMutStatic, + hir::ForeignItemStatic(_, false) => Family::ForeignImmStatic + }; + self.encode_family(family); + + self.start_tag(item_tag::data); + EntryData::Other.encode(self).unwrap(); + self.end_tag(); + + self.start_tag(item_tag::typed_data); + EntryTypedData::Other.encode(self).unwrap(); + self.end_tag(); + + encode_attributes(self, &nitem.attrs); + encode_stability(self, def_id); } } @@ -1267,21 +967,25 @@ impl<'a, 'b, 'tcx> IndexBuilder<'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); + self.encode_def_key(def_id); self.encode_bounds_and_type_for_item(def_id); } fn encode_info_for_closure(&mut self, def_id: DefId) { let tcx = self.tcx; - encode_def_id_and_key(self, def_id); - encode_name(self, syntax::parse::token::intern("")); + self.encode_def_key(def_id); + self.encode_family(Family::Closure); - self.start_tag(item_tag::closure_ty); - tcx.tables.borrow().closure_tys[&def_id].encode(self).unwrap(); + self.start_tag(item_tag::data); + EntryData::Closure(ClosureData { + kind: tcx.closure_kind(def_id) + }).encode(self).unwrap(); self.end_tag(); - self.start_tag(item_tag::closure_kind); - tcx.closure_kind(def_id).encode(self).unwrap(); + self.start_tag(item_tag::typed_data); + EntryTypedData::Closure(ClosureTypedData { + ty: tcx.tables.borrow().closure_tys[&def_id].clone() + }).encode(self).unwrap(); self.end_tag(); assert!(self.mir_map.map.contains_key(&def_id)); @@ -1292,16 +996,14 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { fn encode_info_for_items(ecx: &mut EncodeContext) -> IndexData { let krate = ecx.tcx.map.krate(); - ecx.start_tag(root_tag::items); + // FIXME(eddyb) Avoid wrapping the items in a doc. + ecx.start_tag(0).unwrap(); let items = { let mut index = IndexBuilder::new(ecx); index.record(DefId::local(CRATE_DEF_INDEX), EncodeContext::encode_info_for_mod, - FromId(CRATE_NODE_ID, (&krate.module, - &krate.attrs, - syntax::parse::token::intern(&ecx.link_meta.crate_name), - &hir::Public))); + FromId(CRATE_NODE_ID, (&krate.module, &krate.attrs, &hir::Public))); let mut visitor = EncodeVisitor { index: index, }; @@ -1354,8 +1056,7 @@ fn encode_crate_deps(ecx: &mut EncodeContext, cstore: &cstore::CStore) { // but is enough to get transitive crate dependencies working. ecx.start_tag(root_tag::crate_deps); ecx.seq(&get_ordered_deps(cstore), |_, &(_, ref dep)| { - (dep.name(), decoder::get_crate_hash(dep.data()), - dep.explicitly_linked.get()) + (dep.name(), dep.hash(), dep.explicitly_linked.get()) }); ecx.end_tag(); } @@ -1406,18 +1107,6 @@ fn encode_native_libraries(ecx: &mut EncodeContext) { ecx.end_tag(); } -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.start_tag(root_tag::plugin_registrar_fn); - def_id.index.encode(ecx).unwrap(); - ecx.end_tag(); - } - None => {} - } -} - fn encode_codemap(ecx: &mut EncodeContext) { let codemap = ecx.tcx.sess.codemap(); let all_filemaps = codemap.files.borrow(); @@ -1448,15 +1137,6 @@ fn encode_macro_defs(ecx: &mut EncodeContext) { (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.start_tag(root_tag::macro_derive_registrar); - did.index.encode(ecx).unwrap(); - ecx.end_tag(); - } } struct ImplVisitor<'a, 'tcx:'a> { @@ -1601,30 +1281,29 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) { let tcx = ecx.tcx; let link_meta = ecx.link_meta; - ecx.start_tag(root_tag::crate_crate_name); - link_meta.crate_name.encode(ecx).unwrap(); - ecx.end_tag(); - - ecx.start_tag(root_tag::crate_triple); - tcx.sess.opts.target_triple.encode(ecx).unwrap(); - ecx.end_tag(); - - ecx.start_tag(root_tag::crate_hash); - link_meta.crate_hash.encode(ecx).unwrap(); - ecx.end_tag(); - - ecx.start_tag(root_tag::crate_disambiguator); - tcx.sess.local_crate_disambiguator().encode(ecx).unwrap(); - ecx.end_tag(); - - encode_dylib_dependency_formats(ecx); - - ecx.start_tag(root_tag::panic_strategy); - ecx.tcx.sess.opts.cg.panic.encode(ecx); + ecx.start_tag(root_tag::crate_info); + let is_rustc_macro = tcx.sess.crate_types.borrow().contains(&CrateTypeRustcMacro); + CrateInfo { + name: link_meta.crate_name.clone(), + triple: tcx.sess.opts.target_triple.clone(), + hash: link_meta.crate_hash, + disambiguator: tcx.sess.local_crate_disambiguator().to_string(), + panic_strategy: tcx.sess.opts.cg.panic.clone(), + plugin_registrar_fn: tcx.sess.plugin_registrar_fn.get().map(|id| { + tcx.map.local_def_id(id).index + }), + macro_derive_registrar: if is_rustc_macro { + let id = tcx.sess.derive_registrar_fn.get().unwrap(); + Some(tcx.map.local_def_id(id).index) + } else { + None + } + }.encode(ecx).unwrap(); ecx.end_tag(); let mut i = ecx.position(); encode_crate_deps(ecx, ecx.cstore); + encode_dylib_dependency_formats(ecx); let dep_bytes = ecx.position() - i; // Encode the language items. @@ -1637,11 +1316,6 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) { encode_native_libraries(ecx); let native_lib_bytes = ecx.position() - i; - // Encode the plugin registrar function - i = ecx.position(); - encode_plugin_registrar_fn(ecx); - let plugin_registrar_fn_bytes = ecx.position() - i; - // Encode codemap i = ecx.position(); encode_codemap(ecx); @@ -1689,7 +1363,6 @@ fn encode_metadata_inner(ecx: &mut EncodeContext) { println!(" dep bytes: {}", dep_bytes); println!(" lang item bytes: {}", lang_item_bytes); println!(" native bytes: {}", native_lib_bytes); - println!("plugin registrar bytes: {}", plugin_registrar_fn_bytes); println!(" codemap bytes: {}", codemap_bytes); println!(" macro def bytes: {}", macro_defs_bytes); println!(" impl bytes: {}", impl_bytes); diff --git a/src/librustc_metadata/index.rs b/src/librustc_metadata/index.rs index 63d7f1b58bb..98a43c7639c 100644 --- a/src/librustc_metadata/index.rs +++ b/src/librustc_metadata/index.rs @@ -53,6 +53,18 @@ impl Index { Some(position) } } + + pub fn iter_enumerated<'a>(&self, bytes: &'a [u8]) + -> impl Iterator + 'a { + let words = bytes_to_words(&bytes[self.data_start..self.data_end]); + words.iter().enumerate().filter_map(|(index, &position)| { + if position == u32::MAX { + None + } else { + Some((DefIndex::new(index), u32::from_be(position))) + } + }) + } } /// While we are generating the metadata, we also track the position diff --git a/src/librustc_metadata/lib.rs b/src/librustc_metadata/lib.rs index b7125daa4ad..b46c5be9f8a 100644 --- a/src/librustc_metadata/lib.rs +++ b/src/librustc_metadata/lib.rs @@ -51,26 +51,24 @@ extern crate rustc_const_math; #[cfg(test)] extern crate test; -pub mod rbml { +mod rbml { pub mod writer; pub mod reader; pub use self::reader::Doc; } -pub use rustc::middle; +mod diagnostics; -pub mod diagnostics; - -pub mod astencode; -pub mod common; -pub mod def_key; -pub mod encoder; +mod astencode; +mod common; mod index_builder; -pub mod decoder; +mod index; +mod encoder; +mod decoder; +mod csearch; + pub mod creader; -pub mod csearch; pub mod cstore; -pub mod index; pub mod loader; pub mod macro_import; diff --git a/src/librustc_metadata/loader.rs b/src/librustc_metadata/loader.rs index a4f8ee47799..47bf65bead9 100644 --- a/src/librustc_metadata/loader.rs +++ b/src/librustc_metadata/loader.rs @@ -511,9 +511,8 @@ impl<'a> Context<'a> { if let Some((ref p, _)) = lib.rlib { err.note(&format!("path: {}", p.display())); } - let data = lib.metadata.as_slice(); - let name = decoder::get_crate_name(data); - note_crate_name(&mut err, &name); + let crate_info = decoder::get_crate_info(lib.metadata.as_slice()); + note_crate_name(&mut err, &crate_info.name); } err.emit(); None @@ -610,33 +609,27 @@ impl<'a> Context<'a> { return None; } + let crate_info = decoder::get_crate_info(crate_data); if self.should_match_name { - match decoder::maybe_get_crate_name(crate_data) { - Some(ref name) if self.crate_name == *name => {} - _ => { info!("Rejecting via crate name"); return None } + if self.crate_name != crate_info.name { + info!("Rejecting via crate name"); return None; } } - let hash = match decoder::maybe_get_crate_hash(crate_data) { - None => { info!("Rejecting via lack of crate hash"); return None; } - Some(h) => h, - }; - let triple = match decoder::get_crate_triple(crate_data) { - None => { debug!("triple not present"); return None } - Some(t) => t, - }; - if triple != self.triple { - info!("Rejecting via crate triple: expected {} got {}", self.triple, triple); + if crate_info.triple != self.triple { + info!("Rejecting via crate triple: expected {} got {}", + self.triple, crate_info.triple); self.rejected_via_triple.push(CrateMismatch { path: libpath.to_path_buf(), - got: triple.to_string() + got: crate_info.triple }); return None; } if let Some(myhash) = self.hash { - if *myhash != hash { - info!("Rejecting via hash: expected {} got {}", *myhash, hash); + if *myhash != crate_info.hash { + info!("Rejecting via hash: expected {} got {}", + *myhash, crate_info.hash); self.rejected_via_hash.push(CrateMismatch { path: libpath.to_path_buf(), got: myhash.to_string() @@ -645,7 +638,7 @@ impl<'a> Context<'a> { } } - Some(hash) + Some(crate_info.hash) } diff --git a/src/librustc_mir/hair/cx/expr.rs b/src/librustc_mir/hair/cx/expr.rs index 248690befac..6283ff2187a 100644 --- a/src/librustc_mir/hair/cx/expr.rs +++ b/src/librustc_mir/hair/cx/expr.rs @@ -271,7 +271,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, // Tuple-like ADTs are represented as ExprCall. We convert them here. expr_ty.ty_adt_def().and_then(|adt_def|{ match cx.tcx.expect_def(fun.id) { - Def::Variant(_, variant_id) => { + Def::Variant(variant_id) => { Some((adt_def, adt_def.variant_index_with_id(variant_id))) }, Def::Struct(..) => { @@ -480,8 +480,7 @@ fn make_mirror_unadjusted<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, } AdtKind::Enum => { match cx.tcx.expect_def(expr.id) { - Def::Variant(enum_id, variant_id) => { - debug_assert!(adt.did == enum_id); + Def::Variant(variant_id) => { assert!(base.is_none()); let index = adt.variant_index_with_id(variant_id); @@ -688,13 +687,12 @@ fn convert_path_expr<'a, 'gcx, 'tcx>(cx: &mut Cx<'a, 'gcx, 'tcx>, }, ref sty => bug!("unexpected sty: {:?}", sty) }, - Def::Variant(enum_id, variant_id) => match cx.tcx.node_id_to_type(expr.id).sty { + Def::Variant(variant_id) => match cx.tcx.node_id_to_type(expr.id).sty { // A variant constructor. Should only be reached if not called in the same // expression. ty::TyFnDef(..) => variant_id, // A unit variant, similar special case to the struct case above. ty::TyAdt(adt_def, substs) => { - debug_assert!(adt_def.did == enum_id); let index = adt_def.variant_index_with_id(variant_id); return ExprKind::Adt { adt_def: adt_def, diff --git a/src/librustc_mir/hair/cx/pattern.rs b/src/librustc_mir/hair/cx/pattern.rs index 2c946b078a2..7b8446b184f 100644 --- a/src/librustc_mir/hair/cx/pattern.rs +++ b/src/librustc_mir/hair/cx/pattern.rs @@ -301,7 +301,8 @@ impl<'patcx, 'cx, 'gcx, 'tcx> PatCx<'patcx, 'cx, 'gcx, 'tcx> { subpatterns: Vec>) -> PatternKind<'tcx> { match self.cx.tcx.expect_def(pat.id) { - Def::Variant(enum_id, variant_id) => { + Def::Variant(variant_id) => { + let enum_id = self.cx.tcx.parent_def_id(variant_id).unwrap(); let adt_def = self.cx.tcx.lookup_adt_def(enum_id); if adt_def.variants.len() > 1 { PatternKind::Variant { diff --git a/src/librustc_passes/static_recursion.rs b/src/librustc_passes/static_recursion.rs index d23f77af321..0ab8e2d7fcd 100644 --- a/src/librustc_passes/static_recursion.rs +++ b/src/librustc_passes/static_recursion.rs @@ -272,15 +272,13 @@ impl<'a, 'ast: 'a> Visitor<'ast> for CheckItemRecursionVisitor<'a, 'ast> { // affect the specific variant used, but we need to check // the whole enum definition to see what expression that // might be (if any). - Some(Def::Variant(enum_id, variant_id)) => { - if let Some(enum_node_id) = self.ast_map.as_local_node_id(enum_id) { - if let hir::ItemEnum(ref enum_def, ref generics) = self.ast_map - .expect_item(enum_node_id) - .node { + Some(Def::Variant(variant_id)) => { + if let Some(variant_id) = self.ast_map.as_local_node_id(variant_id) { + let variant = self.ast_map.expect_variant(variant_id); + let enum_id = self.ast_map.get_parent(variant_id); + let enum_item = self.ast_map.expect_item(enum_id); + if let hir::ItemEnum(ref enum_def, ref generics) = enum_item.node { self.populate_enum_discriminants(enum_def); - let enum_id = self.ast_map.as_local_node_id(enum_id).unwrap(); - let variant_id = self.ast_map.as_local_node_id(variant_id).unwrap(); - let variant = self.ast_map.expect_variant(variant_id); self.visit_variant(variant, generics, enum_id); } else { span_bug!(e.span, diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 4012c1cb348..1b119fd0085 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -323,8 +323,13 @@ impl<'b, 'a, 'tcx: 'a, 'v> Visitor<'v> for ReachEverythingInTheInterfaceVisitor< let def = self.ev.tcx.expect_def(ty.id); match def { Def::Struct(def_id) | Def::Union(def_id) | Def::Enum(def_id) | - Def::TyAlias(def_id) | Def::Trait(def_id) | Def::AssociatedTy(def_id, _) => { - if let Some(node_id) = self.ev.tcx.map.as_local_node_id(def_id) { + Def::TyAlias(def_id) | Def::Trait(def_id) | Def::AssociatedTy(def_id) => { + if let Some(mut node_id) = self.ev.tcx.map.as_local_node_id(def_id) { + // Check the trait for associated types. + if let hir::map::NodeTraitItem(_) = self.ev.tcx.map.get(node_id) { + node_id = self.ev.tcx.map.get_parent(node_id); + } + let item = self.ev.tcx.map.expect_item(node_id); if let Def::TyAlias(..) = def { // Type aliases are substituted. Associated type aliases are not @@ -947,9 +952,14 @@ impl<'a, 'tcx: 'a, 'v> Visitor<'v> for SearchInterfaceForPrivateItemsVisitor<'a, return } Def::Struct(def_id) | Def::Union(def_id) | Def::Enum(def_id) | - Def::TyAlias(def_id) | Def::Trait(def_id) | Def::AssociatedTy(def_id, _) => { + Def::TyAlias(def_id) | Def::Trait(def_id) | Def::AssociatedTy(def_id) => { // Non-local means public (private items can't leave their crate, modulo bugs) - if let Some(node_id) = self.tcx.map.as_local_node_id(def_id) { + if let Some(mut node_id) = self.tcx.map.as_local_node_id(def_id) { + // Check the trait for associated types. + if let hir::map::NodeTraitItem(_) = self.tcx.map.get(node_id) { + node_id = self.tcx.map.get_parent(node_id); + } + let item = self.tcx.map.expect_item(node_id); let vis = match self.substituted_alias_visibility(item, path) { Some(vis) => vis, diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 7264dcea955..77a01aac739 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -24,6 +24,7 @@ use {resolve_error, resolve_struct_error, ResolutionError}; use rustc::middle::cstore::ChildItem; use rustc::hir::def::*; use rustc::hir::def_id::{CRATE_DEF_INDEX, DefId}; +use rustc::hir::map::DefPathData; use rustc::ty; use std::cell::Cell; @@ -250,8 +251,7 @@ impl<'b> Resolver<'b> { self.define(parent, name, TypeNS, (module, sp, vis)); for variant in &(*enum_definition).variants { - let item_def_id = self.definitions.local_def_id(item.id); - self.build_reduced_graph_for_variant(variant, item_def_id, module, vis); + self.build_reduced_graph_for_variant(variant, module, vis); } } @@ -314,7 +314,7 @@ impl<'b> Resolver<'b> { is_static_method = !sig.decl.has_self(); (Def::Method(item_def_id), ValueNS) } - TraitItemKind::Type(..) => (Def::AssociatedTy(def_id, item_def_id), TypeNS), + TraitItemKind::Type(..) => (Def::AssociatedTy(item_def_id), TypeNS), TraitItemKind::Macro(_) => panic!("unexpanded macro in resolve!"), }; @@ -334,7 +334,6 @@ impl<'b> Resolver<'b> { // type and value namespaces. fn build_reduced_graph_for_variant(&mut self, variant: &Variant, - item_id: DefId, parent: Module<'b>, vis: ty::Visibility) { let name = variant.node.name.name; @@ -346,7 +345,7 @@ impl<'b> Resolver<'b> { // 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 def = Def::Variant(item_id, self.definitions.local_def_id(variant.node.data.id())); + let def = Def::Variant(self.definitions.local_def_id(variant.node.data.id())); self.define(parent, name, ValueNS, (def, variant.span, vis)); self.define(parent, name, TypeNS, (def, variant.span, vis)); } @@ -389,20 +388,12 @@ 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>, 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); - } - return; - } - 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(..) => { + Def::Mod(_) | Def::Enum(..) => { debug!("(building reduced graph for external crate) building module {} {:?}", name, vis); let parent_link = ModuleParentLink(parent, name); @@ -434,7 +425,8 @@ impl<'b> Resolver<'b> { 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); + self.session.cstore.opt_item_name(trait_item_def) + .expect("opt_item_name returned None for trait"); debug!("(building reduced graph for external crate) ... adding trait item \ '{}'", @@ -452,7 +444,9 @@ impl<'b> Resolver<'b> { let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis)); } Def::Struct(def_id) - if self.session.cstore.tuple_struct_definition_if_ctor(def_id).is_none() => { + if self.session.cstore.def_key(def_id).disambiguated_data.data != + DefPathData::StructCtor + => { debug!("(building reduced graph for external crate) building type and value for {}", name); let _ = self.try_define(parent, name, TypeNS, (def, DUMMY_SP, vis)); diff --git a/src/librustc_resolve/lib.rs b/src/librustc_resolve/lib.rs index b03e76c829a..016b621eabd 100644 --- a/src/librustc_resolve/lib.rs +++ b/src/librustc_resolve/lib.rs @@ -2757,7 +2757,7 @@ impl<'a> Resolver<'a> { if let Some(resolution) = self.def_map.get(&node_id) { match resolution.base_def { Def::Enum(did) | Def::TyAlias(did) | Def::Union(did) | - Def::Struct(did) | Def::Variant(_, did) if resolution.depth == 0 => { + Def::Struct(did) | Def::Variant(did) if resolution.depth == 0 => { if let Some(fields) = self.structs.get(&did) { if fields.iter().any(|&field_name| name == field_name) { return Field; @@ -2826,7 +2826,7 @@ impl<'a> Resolver<'a> { if let Some(path_res) = self.resolve_possibly_assoc_item(expr.id, maybe_qself.as_ref(), path, ValueNS) { // Check if struct variant - let is_struct_variant = if let Def::Variant(_, variant_id) = path_res.base_def { + let is_struct_variant = if let Def::Variant(variant_id) = path_res.base_def { self.structs.contains_key(&variant_id) } else { false diff --git a/src/librustc_save_analysis/dump_visitor.rs b/src/librustc_save_analysis/dump_visitor.rs index 2cbc110c56a..79fcff7d8a1 100644 --- a/src/librustc_save_analysis/dump_visitor.rs +++ b/src/librustc_save_analysis/dump_visitor.rs @@ -293,8 +293,7 @@ impl<'l, 'tcx: 'l, 'll, D: Dump + 'll> DumpVisitor<'l, 'tcx, 'll, D> { let def = self.tcx.expect_def(ref_id); match def { - Def::Mod(_) | - Def::ForeignMod(_) => { + Def::Mod(_) => { self.dumper.mod_ref(ModRefData { span: sub_span.expect("No span found for mod ref"), ref_id: Some(def_id), diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 00c9ea3af18..cbdce3229c7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1373,7 +1373,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { item.expect("missing associated type").def_id() }; - (ty, Def::AssociatedTy(trait_did, item_did)) + (ty, Def::AssociatedTy(item_did)) } fn qpath_to_ty(&self, @@ -1522,8 +1522,9 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { tcx.prohibit_type_params(base_segments); tcx.mk_self_type() } - Def::AssociatedTy(trait_did, _) => { + Def::AssociatedTy(def_id) => { tcx.prohibit_type_params(&base_segments[..base_segments.len()-2]); + let trait_did = tcx.parent_def_id(def_id).unwrap(); self.qpath_to_ty(rscope, span, param_mode, diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 3a854da1d48..e38b865842e 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -3224,7 +3224,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { self.set_tainted_by_errors(); return None; } - Def::Variant(type_did, _) | Def::Struct(type_did) | Def::Union(type_did) => { + Def::Variant(did) => { + let type_did = self.tcx.parent_def_id(did).unwrap(); + Some((type_did, self.tcx.expect_variant_def(def))) + } + Def::Struct(type_did) | Def::Union(type_did) => { Some((type_did, self.tcx.expect_variant_def(def))) } Def::TyAlias(did) => { @@ -4115,10 +4119,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Case 1 and 1b. Reference to a *type* or *enum variant*. Def::Struct(def_id) | Def::Union(def_id) | - Def::Variant(_, def_id) | + Def::Variant(def_id) | Def::Enum(def_id) | Def::TyAlias(def_id) | - Def::AssociatedTy(_, def_id) | + Def::AssociatedTy(def_id) | Def::Trait(def_id) => { // Everything but the final segment should have no // parameters at all. @@ -4166,7 +4170,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // here. If they do, an error will have been reported // elsewhere. (I hope) Def::Mod(..) | - Def::ForeignMod(..) | Def::PrimTy(..) | Def::SelfTy(..) | Def::TyParam(..) | diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e72ea60072e..855b135b863 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -17,6 +17,7 @@ use rustc::hir; use rustc::hir::def::Def; use rustc::hir::def_id::DefId; +use rustc::hir::map::DefPathData; use rustc::hir::print as pprust; use rustc::ty::{self, TyCtxt, VariantKind}; use rustc::util::nodemap::FnvHashSet; @@ -82,7 +83,7 @@ fn try_inline_def<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, } Def::Struct(did) // If this is a struct constructor, we skip it - if tcx.sess.cstore.tuple_struct_definition_if_ctor(did).is_none() => { + if tcx.def_key(did).disambiguated_data.data != DefPathData::StructCtor => { record_extern_fqn(cx, did, clean::TypeStruct); ret.extend(build_impls(cx, tcx, did)); clean::StructItem(build_struct(cx, tcx, did)) @@ -497,17 +498,10 @@ fn build_module<'a, 'tcx>(cx: &DocContext, tcx: TyCtxt<'a, 'tcx, 'tcx>, // visit each node at most once. let mut visited = FnvHashSet(); for item in tcx.sess.cstore.item_children(did) { - match item.def { - Def::ForeignMod(did) => { - fill_in(cx, tcx, did, items); - } - 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) - } - } + if item.vis == ty::Visibility::Public { + if !visited.insert(item.def) { continue } + if let Some(i) = try_inline_def(cx, tcx, item.def) { + items.extend(i) } } } diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index f9d7eb50eda..43a9b4e49e3 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1161,7 +1161,7 @@ impl<'a, 'tcx> Clean for (DefId, &'a ty::PolyFnSig<'tcx>) { let mut names = if cx.map.as_local_node_id(did).is_some() { vec![].into_iter() } else { - cx.tcx().sess.cstore.method_arg_names(did).into_iter() + cx.tcx().sess.cstore.fn_arg_names(did).into_iter() }.peekable(); FnDecl { output: Return(sig.0.output.clean(cx)), @@ -2757,6 +2757,8 @@ fn resolve_type(cx: &DocContext, fn register_def(cx: &DocContext, def: Def) -> DefId { debug!("register_def({:?})", def); + let tcx = cx.tcx(); + let (did, kind) = match def { Def::Fn(i) => (i, TypeFunction), Def::TyAlias(i) => (i, TypeTypedef), @@ -2766,7 +2768,7 @@ fn register_def(cx: &DocContext, def: Def) -> DefId { Def::Union(i) => (i, TypeUnion), Def::Mod(i) => (i, TypeModule), Def::Static(i, _) => (i, TypeStatic), - Def::Variant(i, _) => (i, TypeEnum), + Def::Variant(i) => (tcx.parent_def_id(i).unwrap(), TypeEnum), Def::SelfTy(Some(def_id), _) => (def_id, TypeTrait), Def::SelfTy(_, Some(impl_def_id)) => { return impl_def_id @@ -2774,10 +2776,6 @@ fn register_def(cx: &DocContext, def: Def) -> DefId { _ => return def.def_id() }; if did.is_local() { return did } - let tcx = match cx.tcx_opt() { - Some(tcx) => tcx, - None => return did - }; inline::record_extern_fqn(cx, did, kind); if let TypeTrait = kind { let t = inline::build_external_trait(cx, tcx, did); diff --git a/src/librustdoc/visit_lib.rs b/src/librustdoc/visit_lib.rs index da11f652b4b..d93ca75a8da 100644 --- a/src/librustdoc/visit_lib.rs +++ b/src/librustdoc/visit_lib.rs @@ -68,7 +68,6 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> { for item in self.cstore.item_children(did) { match item.def { Def::Mod(did) | - Def::ForeignMod(did) | Def::Trait(did) | Def::Struct(did) | Def::Union(did) | @@ -84,9 +83,10 @@ impl<'a, 'b, 'tcx> LibEmbargoVisitor<'a, 'b, 'tcx> { } fn visit_item(&mut self, did: DefId, item: ChildItem) { - let inherited_item_level = match item.def { - Def::ForeignMod(..) => self.prev_level, - _ => if item.vis == Visibility::Public { self.prev_level } else { None } + let inherited_item_level = if item.vis == Visibility::Public { + self.prev_level + } else { + None }; let item_level = self.update(did, inherited_item_level);