From 89736e86716808801732323f3aa848b97fc2b5ba Mon Sep 17 00:00:00 2001
From: Eduard Burtescu <edy.burt@gmail.com>
Date: Mon, 5 Sep 2016 10:54:38 +0300
Subject: [PATCH] rustc: remove ImplOrTraitItemId and TraitDef's
 associated_type_names.

---
 src/librustc/dep_graph/dep_node.rs            |  6 +-
 src/librustc/middle/cstore.rs                 |  4 +-
 src/librustc/middle/dead.rs                   |  7 +--
 src/librustc/middle/stability.rs              |  7 +--
 .../traits/specialize/specialization_graph.rs |  4 +-
 src/librustc/ty/context.rs                    |  6 +-
 src/librustc/ty/maps.rs                       |  3 +-
 src/librustc/ty/mod.rs                        | 55 ++++--------------
 src/librustc/ty/trait_def.rs                  |  7 ---
 src/librustc_const_eval/eval.rs               | 12 ++--
 src/librustc_metadata/common.rs               |  3 -
 src/librustc_metadata/csearch.rs              | 11 +++-
 src/librustc_metadata/decoder.rs              | 27 +--------
 src/librustc_metadata/encoder.rs              | 17 +-----
 src/librustc_resolve/build_reduced_graph.rs   |  4 +-
 src/librustc_save_analysis/lib.rs             | 14 ++---
 src/librustc_trans/meth.rs                    | 18 +++---
 src/librustc_trans/mir/constant.rs            | 12 ++--
 src/librustc_typeck/astconv.rs                | 27 +++++----
 src/librustc_typeck/check/method/mod.rs       |  2 +-
 src/librustc_typeck/check/mod.rs              |  8 ++-
 src/librustc_typeck/coherence/mod.rs          | 24 ++------
 src/librustc_typeck/coherence/overlap.rs      | 22 ++++----
 src/librustc_typeck/collect.rs                | 56 ++++++++-----------
 src/librustc_typeck/lib.rs                    |  1 +
 src/librustdoc/clean/inline.rs                |  6 +-
 26 files changed, 130 insertions(+), 233 deletions(-)

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<D: Clone + Debug> {
     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<D: Clone + Debug> DepNode<D> {
             ImplOrTraitItems,
             ItemSignature,
             FieldTy,
-            ImplOrTraitItemIds,
+            ImplOrTraitItemDefIds,
             InherentImpls,
             TraitImpls,
             ReprHints,
@@ -225,7 +225,7 @@ impl<D: Clone + Debug> DepNode<D> {
             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<DefId>) -> Vec<DefId>;
 
     // impl info
-    fn impl_or_trait_items(&self, def_id: DefId) -> Vec<ty::ImplOrTraitItemId>;
+    fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId>;
     fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                           -> Option<ty::TraitRef<'tcx>>;
     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<ty::ImplOrTraitItemId>
+    fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId>
         { bug!("impl_or_trait_items") }
     fn impl_trait_ref<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                           -> Option<ty::TraitRef<'tcx>> { 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<Vec<ty::ImplOrTraitItemId>>,
+    items: Rc<Vec<DefId>>,
     idx: usize
 }
 
@@ -312,7 +312,7 @@ impl<'a, 'tcx> Iterator for NodeItems<'a, 'tcx> {
     type Item = ImplOrTraitItem<'tcx>;
     fn next(&mut self) -> Option<ImplOrTraitItem<'tcx>> {
         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<DepTrackingMap<maps::ImplOrTraitItems<'tcx>>>,
 
     /// Maps from an impl/trait def-id to a list of the def-ids of its items
-    pub impl_or_trait_item_ids: RefCell<DepTrackingMap<maps::ImplOrTraitItemIds<'tcx>>>,
+    pub impl_or_trait_item_def_ids: RefCell<DepTrackingMap<maps::ImplOrTraitItemDefIds<'tcx>>>,
 
     /// 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<Vec<ty::ImplOrTraitItemId>> }
+dep_map_ty! { ImplOrTraitItemDefIds: ImplOrTraitItemDefIds(DefId) -> Rc<Vec<DefId>> }
 dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option<ty::TraitRef<'tcx>> }
 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<Rc<Method<'gcx>>> {
-        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<Vec<ImplOrTraitItemId>> {
+    pub fn impl_or_trait_items(self, id: DefId) -> Rc<Vec<DefId>> {
         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<ImplOrTraitItemId> {
+    pub fn trait_item_of_item(self, def_id: DefId) -> Option<DefId> {
         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<Name>,
-
     // 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<Name>,
                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<ty::ImplOrTraitItemId> {
+    fn impl_or_trait_items(&self, def_id: DefId) -> Vec<DefId> {
         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<Def> {
     })
 }
 
-fn parse_associated_type_names(item_doc: rbml::Doc) -> Vec<ast::Name> {
-    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<ty::ImplOrTraitItemId> {
-    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<cstore::CrateMetadata>)> {
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<ImplOrTraitItemId> {
+    fn create_impl_from_item(&self, item: &Item) -> Vec<DefId> {
         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<Item=ast::Name> + '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);