diff --git a/src/librustc/dep_graph/dep_node.rs b/src/librustc/dep_graph/dep_node.rs index 3cf7548e320..269f0ebb813 100644 --- a/src/librustc/dep_graph/dep_node.rs +++ b/src/librustc/dep_graph/dep_node.rs @@ -108,7 +108,7 @@ pub enum DepNode { ItemSignature(D), FieldTy(D), SizedConstraint(D), - ImplOrTraitItemIds(D), + ImplOrTraitItemDefIds(D), InherentImpls(D), // The set of impls for a given trait. Ultimately, it would be @@ -157,7 +157,7 @@ impl DepNode { ImplOrTraitItems, ItemSignature, FieldTy, - ImplOrTraitItemIds, + ImplOrTraitItemDefIds, InherentImpls, TraitImpls, ReprHints, @@ -225,7 +225,7 @@ impl DepNode { ItemSignature(ref d) => op(d).map(ItemSignature), FieldTy(ref d) => op(d).map(FieldTy), SizedConstraint(ref d) => op(d).map(SizedConstraint), - ImplOrTraitItemIds(ref d) => op(d).map(ImplOrTraitItemIds), + ImplOrTraitItemDefIds(ref d) => op(d).map(ImplOrTraitItemDefIds), InherentImpls(ref d) => op(d).map(InherentImpls), TraitImpls(ref d) => op(d).map(TraitImpls), TraitItems(ref d) => op(d).map(TraitItems), diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index 52cadd76c64..e844ec37dc7 100644 --- a/src/librustc/middle/cstore.rs +++ b/src/librustc/middle/cstore.rs @@ -157,7 +157,7 @@ pub trait CrateStore<'tcx> { fn implementations_of_trait(&self, filter: Option) -> Vec; // impl info - fn impl_or_trait_items(&self, def_id: DefId) -> Vec; + fn impl_or_trait_items(&self, def_id: DefId) -> Vec; fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Option>; fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity; @@ -329,7 +329,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore { } // impl info - fn impl_or_trait_items(&self, def_id: DefId) -> Vec + fn impl_or_trait_items(&self, def_id: DefId) -> Vec { bug!("impl_or_trait_items") } fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> Option> { bug!("impl_trait_ref") } diff --git a/src/librustc/middle/dead.rs b/src/librustc/middle/dead.rs index 2c952e9f863..70232d4f01e 100644 --- a/src/librustc/middle/dead.rs +++ b/src/librustc/middle/dead.rs @@ -470,13 +470,12 @@ impl<'a, 'tcx> DeadVisitor<'a, 'tcx> { // This is done to handle the case where, for example, the static // method of a private type is used, but the type itself is never // called directly. - let impl_items = self.tcx.impl_or_trait_item_ids.borrow(); + let impl_items = self.tcx.impl_or_trait_item_def_ids.borrow(); if let Some(impl_list) = self.tcx.inherent_impls.borrow().get(&self.tcx.map.local_def_id(id)) { for impl_did in impl_list.iter() { - for item_did in impl_items.get(impl_did).unwrap().iter() { - if let Some(item_node_id) = - self.tcx.map.as_local_node_id(item_did.def_id()) { + for &item_did in &impl_items[impl_did][..] { + if let Some(item_node_id) = self.tcx.map.as_local_node_id(item_did) { if self.live_symbols.contains(&item_node_id) { return true; } diff --git a/src/librustc/middle/stability.rs b/src/librustc/middle/stability.rs index e2b997ed60f..2c768db47f1 100644 --- a/src/librustc/middle/stability.rs +++ b/src/librustc/middle/stability.rs @@ -695,10 +695,9 @@ fn is_internal<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, span: Span) -> bool { fn is_staged_api<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, id: DefId) -> bool { match tcx.trait_item_of_item(id) { - Some(ty::MethodTraitItemId(trait_method_id)) - if trait_method_id != id => { - is_staged_api(tcx, trait_method_id) - } + Some(trait_method_id) if trait_method_id != id => { + is_staged_api(tcx, trait_method_id) + } _ => { *tcx.stability.borrow_mut().staged_api.entry(id.krate).or_insert_with( || tcx.sess.cstore.is_staged_api(id.krate)) diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs index 4339b1a254f..1374719ef49 100644 --- a/src/librustc/traits/specialize/specialization_graph.rs +++ b/src/librustc/traits/specialize/specialization_graph.rs @@ -304,7 +304,7 @@ impl<'a, 'gcx, 'tcx> Node { /// An iterator over the items defined within a trait or impl. pub struct NodeItems<'a, 'tcx: 'a> { tcx: TyCtxt<'a, 'tcx, 'tcx>, - items: Rc>, + items: Rc>, idx: usize } @@ -312,7 +312,7 @@ impl<'a, 'tcx> Iterator for NodeItems<'a, 'tcx> { type Item = ImplOrTraitItem<'tcx>; fn next(&mut self) -> Option> { if self.idx < self.items.len() { - let item_def_id = self.items[self.idx].def_id(); + let item_def_id = self.items[self.idx]; let items_table = self.tcx.impl_or_trait_items.borrow(); let item = items_table[&item_def_id].clone(); self.idx += 1; diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs index 0d6beb34c69..1c9238646df 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -331,7 +331,7 @@ pub struct GlobalCtxt<'tcx> { pub impl_or_trait_items: RefCell>>, /// Maps from an impl/trait def-id to a list of the def-ids of its items - pub impl_or_trait_item_ids: RefCell>>, + pub impl_or_trait_item_def_ids: RefCell>>, /// A cache for the trait_items() routine; note that the routine /// itself pushes the `TraitItems` dependency node. @@ -728,7 +728,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { rcache: RefCell::new(FnvHashMap()), tc_cache: RefCell::new(FnvHashMap()), impl_or_trait_items: RefCell::new(DepTrackingMap::new(dep_graph.clone())), - impl_or_trait_item_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())), + impl_or_trait_item_def_ids: RefCell::new(DepTrackingMap::new(dep_graph.clone())), trait_items_cache: RefCell::new(DepTrackingMap::new(dep_graph.clone())), ty_param_defs: RefCell::new(NodeMap()), normalized_cache: RefCell::new(FnvHashMap()), @@ -1396,7 +1396,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { self.trait_items_cache.memoize(trait_did, || { let def_ids = self.impl_or_trait_items(trait_did); Rc::new(def_ids.iter() - .map(|d| self.impl_or_trait_item(d.def_id())) + .map(|&def_id| self.impl_or_trait_item(def_id)) .collect()) }) } diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs index 5e029cf98dc..3a552a8b437 100644 --- a/src/librustc/ty/maps.rs +++ b/src/librustc/ty/maps.rs @@ -34,8 +34,7 @@ dep_map_ty! { Tcache: ItemSignature(DefId) -> Ty<'tcx> } dep_map_ty! { Generics: ItemSignature(DefId) -> &'tcx ty::Generics<'tcx> } dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> } dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> } -dep_map_ty! { ImplOrTraitItemIds: ImplOrTraitItemIds(DefId) - -> Rc> } +dep_map_ty! { ImplOrTraitItemDefIds: ImplOrTraitItemDefIds(DefId) -> Rc> } dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option> } dep_map_ty! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef<'tcx> } dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 3eb9f8593e3..8aba6329b09 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -8,7 +8,6 @@ // option. This file may not be copied, modified, or distributed // except according to those terms. -pub use self::ImplOrTraitItemId::*; pub use self::Variance::*; pub use self::DtorKind::*; pub use self::ImplOrTraitItemContainer::*; @@ -190,18 +189,6 @@ pub enum ImplOrTraitItem<'tcx> { } impl<'tcx> ImplOrTraitItem<'tcx> { - fn id(&self) -> ImplOrTraitItemId { - match *self { - ConstTraitItem(ref associated_const) => { - ConstTraitItemId(associated_const.def_id) - } - MethodTraitItem(ref method) => MethodTraitItemId(method.def_id), - TypeTraitItem(ref associated_type) => { - TypeTraitItemId(associated_type.def_id) - } - } - } - pub fn def(&self) -> Def { match *self { ConstTraitItem(ref associated_const) => Def::AssociatedConst(associated_const.def_id), @@ -250,23 +237,6 @@ impl<'tcx> ImplOrTraitItem<'tcx> { } } -#[derive(Clone, Copy, Debug, RustcEncodable, RustcDecodable)] -pub enum ImplOrTraitItemId { - ConstTraitItemId(DefId), - MethodTraitItemId(DefId), - TypeTraitItemId(DefId), -} - -impl ImplOrTraitItemId { - pub fn def_id(&self) -> DefId { - match *self { - ConstTraitItemId(def_id) => def_id, - MethodTraitItemId(def_id) => def_id, - TypeTraitItemId(def_id) => def_id, - } - } -} - #[derive(Clone, Debug, PartialEq, Eq, Copy, RustcEncodable, RustcDecodable)] pub enum Visibility { /// Visible everywhere (including in other crates). @@ -2276,8 +2246,8 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } pub fn provided_trait_methods(self, id: DefId) -> Vec>> { - self.impl_or_trait_items(id).iter().filter_map(|id| { - match self.impl_or_trait_item(id.def_id()) { + self.impl_or_trait_items(id).iter().filter_map(|&def_id| { + match self.impl_or_trait_item(def_id) { MethodTraitItem(ref m) if m.has_body => Some(m.clone()), _ => None } @@ -2321,9 +2291,9 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { .expect("missing ImplOrTraitItem in metadata")) } - pub fn impl_or_trait_items(self, id: DefId) -> Rc> { + pub fn impl_or_trait_items(self, id: DefId) -> Rc> { lookup_locally_or_in_crate_store( - "impl_or_trait_items", id, &self.impl_or_trait_item_ids, + "impl_or_trait_items", id, &self.impl_or_trait_item_def_ids, || Rc::new(self.sess.cstore.impl_or_trait_items(id))) } @@ -2600,7 +2570,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { let impl_items = self.sess.cstore.impl_or_trait_items(primitive_def_id); // Store the implementation info. - self.impl_or_trait_item_ids.borrow_mut().insert(primitive_def_id, Rc::new(impl_items)); + self.impl_or_trait_item_def_ids.borrow_mut().insert(primitive_def_id, Rc::new(impl_items)); self.populated_external_primitive_impls.borrow_mut().insert(primitive_def_id); } @@ -2627,7 +2597,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { for &impl_def_id in &inherent_impls { // Store the implementation info. let impl_items = self.sess.cstore.impl_or_trait_items(impl_def_id); - self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items)); + self.impl_or_trait_item_def_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items)); } self.inherent_impls.borrow_mut().insert(type_id, inherent_impls); @@ -2669,15 +2639,14 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { // For any methods that use a default implementation, add them to // the map. This is a bit unfortunate. - for impl_item_def_id in &impl_items { - let method_def_id = impl_item_def_id.def_id(); + for &impl_item_def_id in &impl_items { // load impl items eagerly for convenience // FIXME: we may want to load these lazily - self.impl_or_trait_item(method_def_id); + self.impl_or_trait_item(impl_item_def_id); } // Store the implementation info. - self.impl_or_trait_item_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items)); + self.impl_or_trait_item_def_ids.borrow_mut().insert(impl_def_id, Rc::new(impl_items)); } def.flags.set(def.flags.get() | TraitFlags::IMPLS_VALID); @@ -2766,19 +2735,19 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { /// is already that of the original trait method, then the return value is /// the same). /// Otherwise, return `None`. - pub fn trait_item_of_item(self, def_id: DefId) -> Option { + pub fn trait_item_of_item(self, def_id: DefId) -> Option { let impl_or_trait_item = match self.impl_or_trait_items.borrow().get(&def_id) { Some(m) => m.clone(), None => return None, }; match impl_or_trait_item.container() { - TraitContainer(_) => Some(impl_or_trait_item.id()), + TraitContainer(_) => Some(impl_or_trait_item.def_id()), ImplContainer(def_id) => { self.trait_id_of_impl(def_id).and_then(|trait_did| { let name = impl_or_trait_item.name(); self.trait_items(trait_did).iter() .find(|item| item.name() == name) - .map(|item| item.id()) + .map(|item| item.def_id()) }) } } diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs index 268b2fcaa4a..3ff2ed76e57 100644 --- a/src/librustc/ty/trait_def.rs +++ b/src/librustc/ty/trait_def.rs @@ -15,7 +15,6 @@ use ty; use ty::fast_reject; use ty::{Ty, TyCtxt, TraitRef}; use std::cell::{Cell, RefCell}; -use syntax::ast::Name; use hir; use util::nodemap::FnvHashMap; @@ -38,10 +37,6 @@ pub struct TraitDef<'tcx> { pub trait_ref: ty::TraitRef<'tcx>, - /// A list of the associated types defined in this trait. Useful - /// for resolving `X::Foo` type markers. - pub associated_type_names: Vec, - // Impls of a trait. To allow for quicker lookup, the impls are indexed by a // simplified version of their `Self` type: impls with a simplifiable `Self` // are stored in `nonblanket_impls` keyed by it, while all other impls are @@ -82,7 +77,6 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> { paren_sugar: bool, generics: &'tcx ty::Generics<'tcx>, trait_ref: ty::TraitRef<'tcx>, - associated_type_names: Vec, def_path_hash: u64) -> TraitDef<'tcx> { TraitDef { @@ -90,7 +84,6 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> { unsafety: unsafety, generics: generics, trait_ref: trait_ref, - associated_type_names: associated_type_names, nonblanket_impls: RefCell::new(FnvHashMap()), blanket_impls: RefCell::new(vec![]), flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS), diff --git a/src/librustc_const_eval/eval.rs b/src/librustc_const_eval/eval.rs index fe3c498d184..aa53fdd6e7e 100644 --- a/src/librustc_const_eval/eval.rs +++ b/src/librustc_const_eval/eval.rs @@ -1081,16 +1081,14 @@ fn resolve_trait_associated_const<'a, 'tcx: 'a>(tcx: TyCtxt<'a, 'tcx, 'tcx>, match selection { traits::VtableImpl(ref impl_data) => { let ac = tcx.impl_or_trait_items(impl_data.impl_def_id) - .iter().filter_map(|id| { - match *id { - ty::ConstTraitItemId(def_id) => { - Some(tcx.impl_or_trait_item(def_id)) - } + .iter().filter_map(|&def_id| { + match tcx.impl_or_trait_item(def_id) { + ty::ConstTraitItem(ic) => Some(ic), _ => None } - }).find(|ic| ic.name() == ti.name); + }).find(|ic| ic.name == ti.name); match ac { - Some(ic) => lookup_const_by_id(tcx, ic.def_id(), None), + Some(ic) => lookup_const_by_id(tcx, ic.def_id, None), None => match ti.node { hir::ConstTraitItem(ref ty, Some(ref expr)) => { Some((&*expr, tcx.ast_ty_to_prim_ty(ty))) diff --git a/src/librustc_metadata/common.rs b/src/librustc_metadata/common.rs index 94581a3fc89..6df8c7de415 100644 --- a/src/librustc_metadata/common.rs +++ b/src/librustc_metadata/common.rs @@ -166,9 +166,6 @@ pub const tag_item_predicates: usize = 0x95; pub const tag_unsafety: usize = 0x9a; -pub const tag_associated_type_names: usize = 0x9b; -pub const tag_associated_type_name: usize = 0x9c; - pub const tag_polarity: usize = 0x9d; pub const tag_macro_defs: usize = 0x10e; // top-level only diff --git a/src/librustc_metadata/csearch.rs b/src/librustc_metadata/csearch.rs index 38b18fa63e3..c4ce7af269d 100644 --- a/src/librustc_metadata/csearch.rs +++ b/src/librustc_metadata/csearch.rs @@ -179,10 +179,15 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore { result } - fn impl_or_trait_items(&self, def_id: DefId) -> Vec { + fn impl_or_trait_items(&self, def_id: DefId) -> Vec { self.dep_graph.read(DepNode::MetaData(def_id)); - let cdata = self.get_crate_data(def_id.krate); - decoder::get_impl_or_trait_items(&cdata, def_id.index) + 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()); + }); + result } fn impl_polarity(&self, def: DefId) -> hir::ImplPolarity diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs index 507e6414181..8b87f0e718f 100644 --- a/src/librustc_metadata/decoder.rs +++ b/src/librustc_metadata/decoder.rs @@ -453,10 +453,6 @@ fn item_to_def(cdata: Cmd, item: rbml::Doc, did: DefId) -> Option { }) } -fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec { - item_doc.get(tag_associated_type_names).decoder().decode() -} - pub fn get_trait_def<'a, 'tcx>(cdata: Cmd, item_id: DefIndex, tcx: TyCtxt<'a, 'tcx, 'tcx>) -> ty::TraitDef<'tcx> @@ -464,16 +460,11 @@ 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(tag_unsafety).decoder().decode(); - let associated_type_names = parse_associated_type_names(item_doc); let paren_sugar = item_doc.get(tag_paren_sugar).decoder().decode(); let trait_ref = doc_trait_ref(item_doc.get(tag_item_trait_ref), tcx, cdata); let def_path = def_path(cdata, item_id).unwrap(); - ty::TraitDef::new(unsafety, - paren_sugar, - generics, - trait_ref, - associated_type_names, + ty::TraitDef::new(unsafety, paren_sugar, generics, trait_ref, def_path.deterministic_hash(tcx)) } @@ -855,22 +846,6 @@ fn get_explicit_self<'a, 'tcx>(cdata: Cmd, item: rbml::Doc, tcx: TyCtxt<'a, 'tcx dcx.decode() } -/// Returns the def IDs of all the items in the given implementation. -pub fn get_impl_or_trait_items(cdata: Cmd, impl_id: DefIndex) - -> Vec { - let item = cdata.lookup_item(impl_id); - let mut dcx = item.get(tag_mod_children).decoder(); - dcx.cdata = Some(cdata); - dcx.seq().map(|def_id: DefId| { - match item_to_def(cdata, cdata.lookup_item(def_id.index), def_id) { - Some(Def::AssociatedConst(def_id)) => ty::ConstTraitItemId(def_id), - Some(Def::Method(def_id)) => ty::MethodTraitItemId(def_id), - Some(Def::AssociatedTy(_, def_id)) => ty::TypeTraitItemId(def_id), - def => bug!("get_impl_or_trait_items: invalid def {:?}", def) - } - }).collect() -} - pub fn get_trait_name(cdata: Cmd, id: DefIndex) -> ast::Name { let doc = cdata.lookup_item(id); item_name(doc) diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 7b4a6972d22..326eb0fe9a3 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -993,8 +993,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { } self.start_tag(tag_mod_children); - let items = tcx.impl_or_trait_items(def_id); - self.seq(&items[..], |_, id| id.def_id()); + tcx.impl_or_trait_items(def_id).encode(self).unwrap(); <[def::Export]>::encode(&[], self).unwrap(); self.end_tag(); @@ -1039,7 +1038,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { tcx.trait_has_default_impl(def_id).encode(self).unwrap(); self.end_tag(); - encode_associated_type_names(self, &trait_def.associated_type_names); self.encode_generics(&trait_def.generics, &trait_predicates); self.encode_predicates(&tcx.lookup_super_predicates(def_id), tag_item_super_predicates); @@ -1051,8 +1049,7 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> { encode_deprecation(self, depr); self.start_tag(tag_mod_children); - let items = tcx.impl_or_trait_items(def_id); - self.seq(&items[..], |_, id| id.def_id()); + tcx.impl_or_trait_items(def_id).encode(self).unwrap(); <[def::Export]>::encode(&[], self).unwrap(); self.end_tag(); @@ -1151,7 +1148,6 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { None }; - let trait_item_def_id = trait_item_def_id.def_id(); self.record(trait_item_def_id, EncodeContext::encode_info_for_impl_item, (impl_id, trait_item_def_id, ast_item)); @@ -1163,8 +1159,7 @@ impl<'a, 'b, 'tcx> IndexBuilder<'a, 'b, 'tcx> { 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) { - let item_def_id = item_def_id.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, @@ -1331,12 +1326,6 @@ fn encode_attributes(ecx: &mut EncodeContext, attrs: &[ast::Attribute]) { ecx.end_tag(); } -fn encode_associated_type_names(ecx: &mut EncodeContext, names: &[Name]) { - ecx.start_tag(tag_associated_type_names); - names.encode(ecx).unwrap(); - ecx.end_tag(); -} - fn encode_crate_deps(ecx: &mut EncodeContext, cstore: &cstore::CStore) { fn get_ordered_deps(cstore: &cstore::CStore) -> Vec<(CrateNum, Rc)> { diff --git a/src/librustc_resolve/build_reduced_graph.rs b/src/librustc_resolve/build_reduced_graph.rs index 3df3a2decba..7264dcea955 100644 --- a/src/librustc_resolve/build_reduced_graph.rs +++ b/src/librustc_resolve/build_reduced_graph.rs @@ -432,9 +432,9 @@ impl<'b> Resolver<'b> { // info. let trait_item_def_ids = self.session.cstore.impl_or_trait_items(def_id); - for trait_item_def in &trait_item_def_ids { + for &trait_item_def in &trait_item_def_ids { let trait_item_name = - self.session.cstore.item_name(trait_item_def.def_id()); + self.session.cstore.item_name(trait_item_def); debug!("(building reduced graph for external crate) ... adding trait item \ '{}'", diff --git a/src/librustc_save_analysis/lib.rs b/src/librustc_save_analysis/lib.rs index 186183a8ad4..aa68a873120 100644 --- a/src/librustc_save_analysis/lib.rs +++ b/src/librustc_save_analysis/lib.rs @@ -374,8 +374,7 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { let qualname = format!("{}::{}", qualname, name); let def_id = self.tcx.map.local_def_id(id); - let decl_id = self.tcx.trait_item_of_item(def_id).and_then(|new_id| { - let new_def_id = new_id.def_id(); + let decl_id = self.tcx.trait_item_of_item(def_id).and_then(|new_def_id| { if new_def_id != def_id { Some(new_def_id) } else { @@ -543,14 +542,9 @@ impl<'l, 'tcx: 'l> SaveContext<'l, 'tcx> { .map(|mr| mr.def_id()) } ty::ImplContainer(def_id) => { - let impl_items = self.tcx.impl_or_trait_items(def_id); - Some(impl_items.iter() - .find(|mr| { - self.tcx.impl_or_trait_item(mr.def_id()).name() == - ti.name() - }) - .unwrap() - .def_id()) + Some(*self.tcx.impl_or_trait_items(def_id).iter().find(|&&mr| { + self.tcx.impl_or_trait_item(mr).name() == ti.name() + }).unwrap()) } } } else { diff --git a/src/librustc_trans/meth.rs b/src/librustc_trans/meth.rs index 9db5020747e..8540c7a99db 100644 --- a/src/librustc_trans/meth.rs +++ b/src/librustc_trans/meth.rs @@ -235,24 +235,20 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .iter() // Filter out non-method items. - .filter_map(|item_def_id| { - match *item_def_id { - ty::MethodTraitItemId(def_id) => Some(def_id), - _ => None, + .filter_map(|&item_def_id| { + match tcx.impl_or_trait_item(item_def_id) { + ty::MethodTraitItem(m) => Some(m), + _ => None } }) // Now produce pointers for each remaining method. If the // method could never be called from this object, just supply // null. - .map(|trait_method_def_id| { + .map(|trait_method_type| { debug!("get_vtable_methods: trait_method_def_id={:?}", - trait_method_def_id); + trait_method_type.def_id); - let trait_method_type = match tcx.impl_or_trait_item(trait_method_def_id) { - ty::MethodTraitItem(m) => m, - _ => bug!("should be a method, not other assoc item"), - }; let name = trait_method_type.name; // Some methods cannot be called on an object; skip those. @@ -266,7 +262,7 @@ pub fn get_vtable_methods<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, // the method may have some early-bound lifetimes, add // regions for those - let method_substs = Substs::for_item(tcx, trait_method_def_id, + let method_substs = Substs::for_item(tcx, trait_method_type.def_id, |_, _| tcx.mk_region(ty::ReErased), |_, _| tcx.types.err); diff --git a/src/librustc_trans/mir/constant.rs b/src/librustc_trans/mir/constant.rs index 999433db240..cad5ed4f2e6 100644 --- a/src/librustc_trans/mir/constant.rs +++ b/src/librustc_trans/mir/constant.rs @@ -248,16 +248,14 @@ impl<'a, 'tcx> MirConstContext<'a, 'tcx> { if let traits::VtableImpl(vtable_impl) = vtable { let name = ccx.tcx().item_name(instance.def); let ac = ccx.tcx().impl_or_trait_items(vtable_impl.impl_def_id) - .iter().filter_map(|id| { - match *id { - ty::ConstTraitItemId(def_id) => { - Some(ccx.tcx().impl_or_trait_item(def_id)) - } + .iter().filter_map(|&def_id| { + match ccx.tcx().impl_or_trait_item(def_id) { + ty::ConstTraitItem(ac) => Some(ac), _ => None } - }).find(|ic| ic.name() == name); + }).find(|ic| ic.name == name); if let Some(ac) = ac { - instance = Instance::new(ac.def_id(), vtable_impl.substs); + instance = Instance::new(ac.def_id, vtable_impl.substs); } } } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 675c863a3bf..00c9ea3af18 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1134,16 +1134,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { return tcx.types.err; } - let mut associated_types: FnvHashSet<(DefId, ast::Name)> = - traits::supertraits(tcx, principal) - .flat_map(|tr| { - let trait_def = tcx.lookup_trait_def(tr.def_id()); - trait_def.associated_type_names - .clone() - .into_iter() - .map(move |associated_type_name| (tr.def_id(), associated_type_name)) - }) - .collect(); + let mut associated_types = FnvHashSet::default(); + for tr in traits::supertraits(tcx, principal) { + if let Some(trait_id) = tcx.map.as_local_node_id(tr.def_id()) { + use collect::trait_associated_type_names; + + associated_types.extend(trait_associated_type_names(tcx, trait_id) + .map(|name| (tr.def_id(), name))) + } else { + let trait_items = tcx.impl_or_trait_items(tr.def_id()); + associated_types.extend(trait_items.iter().filter_map(|&def_id| { + match tcx.impl_or_trait_item(def_id) { + ty::TypeTraitItem(ref item) => Some(item.name), + _ => None + } + }).map(|name| (tr.def_id(), name))); + } + } for projection_bound in &projection_bounds { let pair = (projection_bound.0.projection_ty.trait_ref.def_id, diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 71219d82668..73caf79c9f8 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -368,7 +368,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { { self.tcx.impl_or_trait_items(def_id) .iter() - .map(|&did| self.tcx.impl_or_trait_item(did.def_id())) + .map(|&did| self.tcx.impl_or_trait_item(did)) .find(|m| m.name() == item_name) } } diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 8d9fd523a8f..3a854da1d48 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1348,8 +1348,12 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> { assoc_name: ast::Name) -> bool { - let trait_def = self.tcx().lookup_trait_def(trait_def_id); - trait_def.associated_type_names.contains(&assoc_name) + self.tcx().impl_or_trait_items(trait_def_id).iter().any(|&def_id| { + match self.tcx().impl_or_trait_item(def_id) { + ty::TypeTraitItem(ref item) => item.name == assoc_name, + _ => false + } + }) } fn ty_infer(&self, _span: Span) -> Ty<'tcx> { diff --git a/src/librustc_typeck/coherence/mod.rs b/src/librustc_typeck/coherence/mod.rs index fb077d279c9..3b4c98fc71e 100644 --- a/src/librustc_typeck/coherence/mod.rs +++ b/src/librustc_typeck/coherence/mod.rs @@ -20,8 +20,7 @@ use middle::lang_items::UnsizeTraitLangItem; use rustc::ty::subst::Subst; use rustc::ty::{self, TyCtxt, TypeFoldable}; use rustc::traits::{self, Reveal}; -use rustc::ty::{ImplOrTraitItemId, ConstTraitItemId}; -use rustc::ty::{MethodTraitItemId, TypeTraitItemId, ParameterEnvironment}; +use rustc::ty::{ParameterEnvironment}; use rustc::ty::{Ty, TyBool, TyChar, TyError}; use rustc::ty::{TyParam, TyRawPtr}; use rustc::ty::{TyRef, TyAdt, TyTrait, TyNever, TyTuple}; @@ -158,7 +157,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { } } - tcx.impl_or_trait_item_ids.borrow_mut().insert(impl_did, Rc::new(impl_items)); + tcx.impl_or_trait_item_def_ids.borrow_mut().insert(impl_did, Rc::new(impl_items)); } fn add_inherent_impl(&self, base_def_id: DefId, impl_def_id: DefId) { @@ -174,22 +173,11 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { } // Converts an implementation in the AST to a vector of items. - fn create_impl_from_item(&self, item: &Item) -> Vec { + fn create_impl_from_item(&self, item: &Item) -> Vec { match item.node { ItemImpl(.., ref impl_items) => { impl_items.iter().map(|impl_item| { - let impl_def_id = self.crate_context.tcx.map.local_def_id(impl_item.id); - match impl_item.node { - hir::ImplItemKind::Const(..) => { - ConstTraitItemId(impl_def_id) - } - hir::ImplItemKind::Method(..) => { - MethodTraitItemId(impl_def_id) - } - hir::ImplItemKind::Type(_) => { - TypeTraitItemId(impl_def_id) - } - } + self.crate_context.tcx.map.local_def_id(impl_item.id) }).collect() } _ => { @@ -210,7 +198,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { tcx.populate_implementations_for_trait_if_necessary(drop_trait); let drop_trait = tcx.lookup_trait_def(drop_trait); - let impl_items = tcx.impl_or_trait_item_ids.borrow(); + let impl_items = tcx.impl_or_trait_item_def_ids.borrow(); drop_trait.for_each_impl(tcx, |impl_did| { let items = impl_items.get(&impl_did).unwrap(); @@ -223,7 +211,7 @@ impl<'a, 'gcx, 'tcx> CoherenceChecker<'a, 'gcx, 'tcx> { let self_type = tcx.lookup_item_type(impl_did); match self_type.ty.sty { ty::TyAdt(type_def, _) => { - type_def.set_destructor(method_def_id.def_id()); + type_def.set_destructor(method_def_id); } _ => { // Destructors only work on nominal types. diff --git a/src/librustc_typeck/coherence/overlap.rs b/src/librustc_typeck/coherence/overlap.rs index 9d072491cc2..c42b8f88400 100644 --- a/src/librustc_typeck/coherence/overlap.rs +++ b/src/librustc_typeck/coherence/overlap.rs @@ -44,29 +44,29 @@ impl<'cx, 'tcx> OverlapChecker<'cx, 'tcx> { enum Namespace { Type, Value } fn name_and_namespace<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, - item: &ty::ImplOrTraitItemId) + def_id: DefId) -> (ast::Name, Namespace) { - let name = tcx.impl_or_trait_item(item.def_id()).name(); - (name, match *item { - ty::TypeTraitItemId(..) => Namespace::Type, - ty::ConstTraitItemId(..) => Namespace::Value, - ty::MethodTraitItemId(..) => Namespace::Value, + let item = tcx.impl_or_trait_item(def_id); + (item.name(), match item { + ty::TypeTraitItem(..) => Namespace::Type, + ty::ConstTraitItem(..) => Namespace::Value, + ty::MethodTraitItem(..) => Namespace::Value, }) } - let impl_items = self.tcx.impl_or_trait_item_ids.borrow(); + let impl_items = self.tcx.impl_or_trait_item_def_ids.borrow(); - for item1 in &impl_items[&impl1][..] { + for &item1 in &impl_items[&impl1][..] { let (name, namespace) = name_and_namespace(self.tcx, item1); - for item2 in &impl_items[&impl2][..] { + for &item2 in &impl_items[&impl2][..] { if (name, namespace) == name_and_namespace(self.tcx, item2) { let msg = format!("duplicate definitions with name `{}`", name); - let node_id = self.tcx.map.as_local_node_id(item1.def_id()).unwrap(); + let node_id = self.tcx.map.as_local_node_id(item1).unwrap(); self.tcx.sess.add_lint(lint::builtin::OVERLAPPING_INHERENT_IMPLS, node_id, - self.tcx.span_of_impl(item1.def_id()).unwrap(), + self.tcx.span_of_impl(item1).unwrap(), msg); } } diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index fa052bec7be..d67dcbb4baf 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -361,10 +361,15 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> { -> bool { if let Some(trait_id) = self.tcx().map.as_local_node_id(trait_def_id) { - trait_defines_associated_type_named(self.ccx, trait_id, assoc_name) + trait_associated_type_names(self.tcx(), trait_id) + .any(|name| name == assoc_name) } else { - let trait_def = self.tcx().lookup_trait_def(trait_def_id); - trait_def.associated_type_names.contains(&assoc_name) + self.tcx().impl_or_trait_items(trait_def_id).iter().any(|&def_id| { + match self.tcx().impl_or_trait_item(def_id) { + ty::TypeTraitItem(ref item) => item.name == assoc_name, + _ => false + } + }) } } @@ -926,15 +931,10 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) { // Add an entry mapping let trait_item_def_ids = Rc::new(trait_items.iter().map(|trait_item| { - let def_id = ccx.tcx.map.local_def_id(trait_item.id); - match trait_item.node { - hir::ConstTraitItem(..) => ty::ConstTraitItemId(def_id), - hir::MethodTraitItem(..) => ty::MethodTraitItemId(def_id), - hir::TypeTraitItem(..) => ty::TypeTraitItemId(def_id) - } + ccx.tcx.map.local_def_id(trait_item.id) }).collect()); - tcx.impl_or_trait_item_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), - trait_item_def_ids); + tcx.impl_or_trait_item_def_ids.borrow_mut().insert(ccx.tcx.map.local_def_id(it.id), + trait_item_def_ids); }, hir::ItemStruct(ref struct_def, _) | hir::ItemUnion(ref struct_def, _) => { @@ -1266,9 +1266,9 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, return def.clone(); } - let (unsafety, generics, items) = match it.node { - hir::ItemTrait(unsafety, ref generics, _, ref items) => { - (unsafety, generics, items) + let (unsafety, generics) = match it.node { + hir::ItemTrait(unsafety, ref generics, _, _) => { + (unsafety, generics) } _ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"), }; @@ -1288,32 +1288,20 @@ fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, let ty_generics = generics_of_def_id(ccx, def_id); let substs = mk_item_substs(&ccx.icx(generics), it.span, def_id); - let associated_type_names: Vec<_> = items.iter().filter_map(|trait_item| { - match trait_item.node { - hir::TypeTraitItem(..) => Some(trait_item.name), - _ => None, - } - }).collect(); - let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx); let trait_ref = ty::TraitRef::new(def_id, substs); - let trait_def = ty::TraitDef::new(unsafety, - paren_sugar, - ty_generics, - trait_ref, - associated_type_names, + let trait_def = ty::TraitDef::new(unsafety, paren_sugar, ty_generics, trait_ref, def_path_hash); tcx.intern_trait_def(trait_def) } -fn trait_defines_associated_type_named(ccx: &CrateCtxt, - trait_node_id: ast::NodeId, - assoc_name: ast::Name) - -> bool +pub fn trait_associated_type_names<'a, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, + trait_node_id: ast::NodeId) + -> impl Iterator + 'a { - let item = match ccx.tcx.map.get(trait_node_id) { + let item = match tcx.map.get(trait_node_id) { hir_map::NodeItem(item) => item, _ => bug!("trait_node_id {} is not an item", trait_node_id) }; @@ -1323,10 +1311,10 @@ fn trait_defines_associated_type_named(ccx: &CrateCtxt, _ => bug!("trait_node_id {} is not a trait", trait_node_id) }; - trait_items.iter().any(|trait_item| { + trait_items.iter().filter_map(|trait_item| { match trait_item.node { - hir::TypeTraitItem(..) => trait_item.name == assoc_name, - _ => false, + hir::TypeTraitItem(..) => Some(trait_item.name), + _ => None, } }) } diff --git a/src/librustc_typeck/lib.rs b/src/librustc_typeck/lib.rs index d2e2d578fce..1f34cee5143 100644 --- a/src/librustc_typeck/lib.rs +++ b/src/librustc_typeck/lib.rs @@ -76,6 +76,7 @@ This API is completely unstable and subject to change. #![feature(box_patterns)] #![feature(box_syntax)] +#![feature(conservative_impl_trait)] #![feature(dotdot_in_tuple_patterns)] #![feature(quote)] #![feature(rustc_diagnostic_macros)] diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs index e992861b77b..e72ea60072e 100644 --- a/src/librustdoc/clean/inline.rs +++ b/src/librustdoc/clean/inline.rs @@ -368,10 +368,8 @@ pub fn build_impl<'a, 'tcx>(cx: &DocContext, let predicates = tcx.lookup_predicates(did); let trait_items = tcx.sess.cstore.impl_or_trait_items(did) .iter() - .filter_map(|did| { - let did = did.def_id(); - let impl_item = tcx.impl_or_trait_item(did); - match impl_item { + .filter_map(|&did| { + match tcx.impl_or_trait_item(did) { ty::ConstTraitItem(ref assoc_const) => { let did = assoc_const.def_id; let type_scheme = tcx.lookup_item_type(did);