about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorEduard-Mihai Burtescu <edy.burt@gmail.com>2016-11-25 02:29:26 +0200
committerEduard-Mihai Burtescu <edy.burt@gmail.com>2016-11-29 21:24:26 +0200
commit3f338eed99265fe5e9a167abb2e1f4a7ff2ea101 (patch)
tree56316a7d7a49ffcc54e0df26f3c320a65822f0a9 /src
parentf50dbd580f3d5d88a300da540db3c85164bfd0de (diff)
downloadrust-3f338eed99265fe5e9a167abb2e1f4a7ff2ea101.tar.gz
rust-3f338eed99265fe5e9a167abb2e1f4a7ff2ea101.zip
rustc: remove type information from TraitDef.
Diffstat (limited to 'src')
-rw-r--r--src/librustc/middle/cstore.rs4
-rw-r--r--src/librustc/traits/error_reporting.rs6
-rw-r--r--src/librustc/traits/object_safety.rs16
-rw-r--r--src/librustc/traits/specialize/specialization_graph.rs14
-rw-r--r--src/librustc/ty/context.rs16
-rw-r--r--src/librustc/ty/maps.rs2
-rw-r--r--src/librustc/ty/mod.rs6
-rw-r--r--src/librustc/ty/subst.rs8
-rw-r--r--src/librustc/ty/trait_def.rs39
-rw-r--r--src/librustc/util/ppaux.rs7
-rw-r--r--src/librustc_metadata/cstore_impl.rs2
-rw-r--r--src/librustc_metadata/decoder.rs7
-rw-r--r--src/librustc_metadata/encoder.rs1
-rw-r--r--src/librustc_metadata/schema.rs1
-rw-r--r--src/librustc_typeck/astconv.rs2
-rw-r--r--src/librustc_typeck/check/method/mod.rs7
-rw-r--r--src/librustc_typeck/check/mod.rs4
-rw-r--r--src/librustc_typeck/check/wfcheck.rs7
-rw-r--r--src/librustc_typeck/collect.rs104
-rw-r--r--src/librustc_typeck/variance/constraints.rs22
-rw-r--r--src/librustdoc/clean/inline.rs5
-rw-r--r--src/librustdoc/clean/mod.rs3
22 files changed, 123 insertions, 160 deletions
diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs
index d055506a382..12557fe4301 100644
--- a/src/librustc/middle/cstore.rs
+++ b/src/librustc/middle/cstore.rs
@@ -277,7 +277,7 @@ pub trait CrateStore<'tcx> {
     fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                          -> ty::Generics<'tcx>;
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>;
-    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>;
+    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef;
     fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>;
     fn fn_arg_names(&self, did: DefId) -> Vec<ast::Name>;
     fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec<DefId>;
@@ -423,7 +423,7 @@ impl<'tcx> CrateStore<'tcx> for DummyCrateStore {
     fn item_generics<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
                          -> ty::Generics<'tcx> { bug!("item_generics") }
     fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute> { bug!("item_attrs") }
-    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef<'tcx>
+    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)-> ty::TraitDef
         { bug!("trait_def") }
     fn adt_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::AdtDefMaster<'tcx>
         { bug!("adt_def") }
diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs
index 21009711cb1..f560308abe0 100644
--- a/src/librustc/traits/error_reporting.rs
+++ b/src/librustc/traits/error_reporting.rs
@@ -244,11 +244,11 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
         for item in self.tcx.get_attrs(def_id).iter() {
             if item.check_name("rustc_on_unimplemented") {
                 let err_sp = item.meta().span.substitute_dummy(span);
-                let def = self.tcx.lookup_trait_def(trait_ref.def_id);
-                let trait_str = def.trait_ref.to_string();
+                let trait_str = self.tcx.item_path_str(trait_ref.def_id);
                 if let Some(istring) = item.value_str() {
                     let istring = &*istring.as_str();
-                    let generic_map = def.generics.types.iter().map(|param| {
+                    let generics = self.tcx.item_generics(trait_ref.def_id);
+                    let generic_map = generics.types.iter().map(|param| {
                         (param.name.as_str().to_string(),
                          trait_ref.substs.type_for_def(param).to_string())
                     }).collect::<FxHashMap<String, String>>();
diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs
index 0681be129b6..ceee6c236e4 100644
--- a/src/librustc/traits/object_safety.rs
+++ b/src/librustc/traits/object_safety.rs
@@ -21,7 +21,8 @@ use super::elaborate_predicates;
 
 use hir::def_id::DefId;
 use traits;
-use ty::{self, ToPolyTraitRef, Ty, TyCtxt, TypeFoldable};
+use ty::{self, Ty, TyCtxt, TypeFoldable};
+use ty::subst::Substs;
 use syntax::ast;
 
 #[derive(Clone, Debug, PartialEq, Eq, Hash)]
@@ -126,9 +127,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     fn supertraits_reference_self(self, trait_def_id: DefId) -> bool {
-        let trait_def = self.lookup_trait_def(trait_def_id);
-        let trait_ref = trait_def.trait_ref.clone();
-        let trait_ref = trait_ref.to_poly_trait_ref();
+        let trait_ref = ty::Binder(ty::TraitRef {
+            def_id: trait_def_id,
+            substs: Substs::identity_for_item(self, trait_def_id)
+        });
         let predicates = self.item_super_predicates(trait_def_id);
         predicates
             .predicates
@@ -317,8 +319,10 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
 
                     // Compute supertraits of current trait lazily.
                     if supertraits.is_none() {
-                        let trait_def = self.lookup_trait_def(trait_def_id);
-                        let trait_ref = ty::Binder(trait_def.trait_ref.clone());
+                        let trait_ref = ty::Binder(ty::TraitRef {
+                            def_id: trait_def_id,
+                            substs: Substs::identity_for_item(self, trait_def_id)
+                        });
                         supertraits = Some(traits::supertraits(self, trait_ref).collect());
                     }
 
diff --git a/src/librustc/traits/specialize/specialization_graph.rs b/src/librustc/traits/specialize/specialization_graph.rs
index 5a6809f1fad..a41523f2def 100644
--- a/src/librustc/traits/specialize/specialization_graph.rs
+++ b/src/librustc/traits/specialize/specialization_graph.rs
@@ -297,18 +297,18 @@ impl<'a, 'gcx, 'tcx> Node {
     }
 }
 
-pub struct Ancestors<'a, 'tcx: 'a> {
-    trait_def: &'a TraitDef<'tcx>,
+pub struct Ancestors<'a> {
+    trait_def: &'a TraitDef,
     current_source: Option<Node>,
 }
 
-impl<'a, 'tcx> Iterator for Ancestors<'a, 'tcx> {
+impl<'a> Iterator for Ancestors<'a> {
     type Item = Node;
     fn next(&mut self) -> Option<Node> {
         let cur = self.current_source.take();
         if let Some(Node::Impl(cur_impl)) = cur {
             let parent = self.trait_def.specialization_graph.borrow().parent(cur_impl);
-            if parent == self.trait_def.def_id() {
+            if parent == self.trait_def.def_id {
                 self.current_source = Some(Node::Trait(parent));
             } else {
                 self.current_source = Some(Node::Impl(parent));
@@ -332,7 +332,7 @@ impl<T> NodeItem<T> {
     }
 }
 
-impl<'a, 'gcx, 'tcx> Ancestors<'a, 'tcx> {
+impl<'a, 'gcx, 'tcx> Ancestors<'a> {
     /// Search the items from the given ancestors, returning each definition
     /// with the given name and the given kind.
     #[inline] // FIXME(#35870) Avoid closures being unexported due to impl Trait.
@@ -347,9 +347,7 @@ impl<'a, 'gcx, 'tcx> Ancestors<'a, 'tcx> {
 
 /// Walk up the specialization ancestors of a given impl, starting with that
 /// impl itself.
-pub fn ancestors<'a, 'tcx>(trait_def: &'a TraitDef<'tcx>,
-                           start_from_impl: DefId)
-                           -> Ancestors<'a, 'tcx> {
+pub fn ancestors<'a>(trait_def: &'a TraitDef, start_from_impl: DefId) -> Ancestors<'a> {
     Ancestors {
         trait_def: trait_def,
         current_source: Some(Node::Impl(start_from_impl)),
diff --git a/src/librustc/ty/context.rs b/src/librustc/ty/context.rs
index ea81c85ba6a..025b35100a7 100644
--- a/src/librustc/ty/context.rs
+++ b/src/librustc/ty/context.rs
@@ -66,7 +66,7 @@ pub struct CtxtArenas<'tcx> {
 
     // references
     generics: TypedArena<ty::Generics<'tcx>>,
-    trait_def: TypedArena<ty::TraitDef<'tcx>>,
+    trait_def: TypedArena<ty::TraitDef>,
     adt_def: TypedArena<ty::AdtDefData<'tcx, 'tcx>>,
     mir: TypedArena<RefCell<Mir<'tcx>>>,
 }
@@ -683,19 +683,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
         self.global_interners.arenas.mir.alloc(RefCell::new(mir))
     }
 
-    pub fn intern_trait_def(self, def: ty::TraitDef<'gcx>)
-                            -> &'gcx ty::TraitDef<'gcx> {
-        let did = def.trait_ref.def_id;
-        let interned = self.alloc_trait_def(def);
-        if let Some(prev) = self.trait_defs.borrow_mut().insert(did, interned) {
-            bug!("Tried to overwrite interned TraitDef: {:?}", prev)
-        }
-        self.generics.borrow_mut().insert(did, interned.generics);
-        interned
-    }
-
-    pub fn alloc_trait_def(self, def: ty::TraitDef<'gcx>)
-                           -> &'gcx ty::TraitDef<'gcx> {
+    pub fn alloc_trait_def(self, def: ty::TraitDef) -> &'gcx ty::TraitDef {
         self.global_interners.arenas.trait_def.alloc(def)
     }
 
diff --git a/src/librustc/ty/maps.rs b/src/librustc/ty/maps.rs
index bf044585879..1fc1c32c2d5 100644
--- a/src/librustc/ty/maps.rs
+++ b/src/librustc/ty/maps.rs
@@ -39,7 +39,7 @@ dep_map_ty! { Predicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
 dep_map_ty! { SuperPredicates: ItemSignature(DefId) -> ty::GenericPredicates<'tcx> }
 dep_map_ty! { AssociatedItemDefIds: AssociatedItemDefIds(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! { TraitDefs: ItemSignature(DefId) -> &'tcx ty::TraitDef }
 dep_map_ty! { AdtDefs: ItemSignature(DefId) -> ty::AdtDefMaster<'tcx> }
 dep_map_ty! { ItemVariances: ItemSignature(DefId) -> Rc<Vec<ty::Variance>> }
 dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec<DefId> }
diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs
index 9a92e9e70fe..288ca751bd4 100644
--- a/src/librustc/ty/mod.rs
+++ b/src/librustc/ty/mod.rs
@@ -629,10 +629,6 @@ pub struct RegionParameterDef<'tcx> {
 }
 
 impl<'tcx> RegionParameterDef<'tcx> {
-    pub fn to_early_bound_region(&self) -> ty::Region {
-        ty::ReEarlyBound(self.to_early_bound_region_data())
-    }
-
     pub fn to_early_bound_region_data(&self) -> ty::EarlyBoundRegion {
         ty::EarlyBoundRegion {
             index: self.index,
@@ -2400,7 +2396,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> {
     }
 
     /// Given the did of a trait, returns its canonical trait ref.
-    pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef<'gcx> {
+    pub fn lookup_trait_def(self, did: DefId) -> &'gcx TraitDef {
         lookup_locally_or_in_crate_store(
             "trait_defs", did, &self.trait_defs,
             || self.alloc_trait_def(self.sess.cstore.trait_def(self.global_tcx(), did))
diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs
index 41fcb09fb2d..d6f61a12a3c 100644
--- a/src/librustc/ty/subst.rs
+++ b/src/librustc/ty/subst.rs
@@ -165,6 +165,14 @@ impl<'tcx> Decodable for Kind<'tcx> {
 pub type Substs<'tcx> = Slice<Kind<'tcx>>;
 
 impl<'a, 'gcx, 'tcx> Substs<'tcx> {
+    /// Creates a Substs that maps each generic parameter to itself.
+    pub fn identity_for_item(tcx: TyCtxt<'a, 'gcx, 'tcx>, def_id: DefId)
+                             -> &'tcx Substs<'tcx> {
+        Substs::for_item(tcx, def_id, |def, _| {
+            tcx.mk_region(ty::ReEarlyBound(def.to_early_bound_region_data()))
+        }, |def, _| tcx.mk_param_from_def(def))
+    }
+
     /// Creates a Substs for generic parameter definitions,
     /// by calling closures to obtain each region and type.
     /// The closures get to observe the Substs as they're
diff --git a/src/librustc/ty/trait_def.rs b/src/librustc/ty/trait_def.rs
index fd81065e61d..c6d862b23bd 100644
--- a/src/librustc/ty/trait_def.rs
+++ b/src/librustc/ty/trait_def.rs
@@ -19,7 +19,9 @@ use hir;
 use util::nodemap::FxHashMap;
 
 /// A trait's definition with type information.
-pub struct TraitDef<'tcx> {
+pub struct TraitDef {
+    pub def_id: DefId,
+
     pub unsafety: hir::Unsafety,
 
     /// If `true`, then this trait had the `#[rustc_paren_sugar]`
@@ -28,15 +30,6 @@ pub struct TraitDef<'tcx> {
     /// be usable with the sugar (or without it).
     pub paren_sugar: bool,
 
-    /// Generic type definitions. Note that `Self` is listed in here
-    /// as having a single bound, the trait itself (e.g., in the trait
-    /// `Eq`, there is a single bound `Self : Eq`). This is so that
-    /// default methods get to assume that the `Self` parameters
-    /// implements the trait.
-    pub generics: &'tcx ty::Generics<'tcx>,
-
-    pub trait_ref: ty::TraitRef<'tcx>,
-
     // 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
@@ -72,18 +65,16 @@ pub struct TraitDef<'tcx> {
     pub def_path_hash: u64,
 }
 
-impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
-    pub fn new(unsafety: hir::Unsafety,
+impl<'a, 'gcx, 'tcx> TraitDef {
+    pub fn new(def_id: DefId,
+               unsafety: hir::Unsafety,
                paren_sugar: bool,
-               generics: &'tcx ty::Generics<'tcx>,
-               trait_ref: ty::TraitRef<'tcx>,
                def_path_hash: u64)
-               -> TraitDef<'tcx> {
+               -> TraitDef {
         TraitDef {
+            def_id: def_id,
             paren_sugar: paren_sugar,
             unsafety: unsafety,
-            generics: generics,
-            trait_ref: trait_ref,
             nonblanket_impls: RefCell::new(FxHashMap()),
             blanket_impls: RefCell::new(vec![]),
             flags: Cell::new(ty::TraitFlags::NO_TRAIT_FLAGS),
@@ -92,10 +83,6 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
         }
     }
 
-    pub fn def_id(&self) -> DefId {
-        self.trait_ref.def_id
-    }
-
     // returns None if not yet calculated
     pub fn object_safety(&self) -> Option<bool> {
         if self.flags.get().intersects(TraitFlags::OBJECT_SAFETY_VALID) {
@@ -117,11 +104,11 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
     }
 
     fn write_trait_impls(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) {
-        tcx.dep_graph.write(DepNode::TraitImpls(self.trait_ref.def_id));
+        tcx.dep_graph.write(DepNode::TraitImpls(self.def_id));
     }
 
     fn read_trait_impls(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) {
-        tcx.dep_graph.read(DepNode::TraitImpls(self.trait_ref.def_id));
+        tcx.dep_graph.read(DepNode::TraitImpls(self.def_id));
     }
 
     /// Records a basic trait-to-implementation mapping.
@@ -203,13 +190,13 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
             .insert(tcx, impl_def_id)
     }
 
-    pub fn ancestors(&'a self, of_impl: DefId) -> specialization_graph::Ancestors<'a, 'tcx> {
+    pub fn ancestors(&'a self, of_impl: DefId) -> specialization_graph::Ancestors<'a> {
         specialization_graph::ancestors(self, of_impl)
     }
 
     pub fn for_each_impl<F: FnMut(DefId)>(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>, mut f: F) {
         self.read_trait_impls(tcx);
-        tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
+        tcx.populate_implementations_for_trait_if_necessary(self.def_id);
 
         for &impl_def_id in self.blanket_impls.borrow().iter() {
             f(impl_def_id);
@@ -231,7 +218,7 @@ impl<'a, 'gcx, 'tcx> TraitDef<'tcx> {
     {
         self.read_trait_impls(tcx);
 
-        tcx.populate_implementations_for_trait_if_necessary(self.trait_ref.def_id);
+        tcx.populate_implementations_for_trait_if_necessary(self.def_id);
 
         for &impl_def_id in self.blanket_impls.borrow().iter() {
             f(impl_def_id);
diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs
index d04825d5604..641b1b54880 100644
--- a/src/librustc/util/ppaux.rs
+++ b/src/librustc/util/ppaux.rs
@@ -432,10 +432,11 @@ impl<'tcx> fmt::Debug for ty::ExistentialTraitRef<'tcx> {
     }
 }
 
-impl<'tcx> fmt::Debug for ty::TraitDef<'tcx> {
+impl fmt::Debug for ty::TraitDef {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
-        write!(f, "TraitDef(generics={:?}, trait_ref={:?})",
-               self.generics, self.trait_ref)
+        ty::tls::with(|tcx| {
+            write!(f, "{}", tcx.item_path_str(self.def_id))
+        })
     }
 }
 
diff --git a/src/librustc_metadata/cstore_impl.rs b/src/librustc_metadata/cstore_impl.rs
index 573b2f6d2a6..624350d84db 100644
--- a/src/librustc_metadata/cstore_impl.rs
+++ b/src/librustc_metadata/cstore_impl.rs
@@ -110,7 +110,7 @@ impl<'tcx> CrateStore<'tcx> for cstore::CStore {
         self.get_crate_data(def_id.krate).get_item_attrs(def_id.index)
     }
 
-    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef<'tcx>
+    fn trait_def<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId) -> ty::TraitDef
     {
         self.dep_graph.read(DepNode::MetaData(def));
         self.get_crate_data(def.krate).get_trait_def(def.index, tcx)
diff --git a/src/librustc_metadata/decoder.rs b/src/librustc_metadata/decoder.rs
index d5b08927a06..d75bab9dc5a 100644
--- a/src/librustc_metadata/decoder.rs
+++ b/src/librustc_metadata/decoder.rs
@@ -531,16 +531,15 @@ impl<'a, 'tcx> CrateMetadata {
     pub fn get_trait_def(&self,
                          item_id: DefIndex,
                          tcx: TyCtxt<'a, 'tcx, 'tcx>)
-                         -> ty::TraitDef<'tcx> {
+                         -> ty::TraitDef {
         let data = match self.entry(item_id).kind {
             EntryKind::Trait(data) => data.decode(self),
             _ => bug!(),
         };
 
-        ty::TraitDef::new(data.unsafety,
+        ty::TraitDef::new(self.local_def_id(item_id),
+                          data.unsafety,
                           data.paren_sugar,
-                          tcx.item_generics(self.local_def_id(item_id)),
-                          data.trait_ref.decode((self, tcx)),
                           self.def_path(item_id).unwrap().deterministic_hash(tcx))
     }
 
diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs
index 4839c409335..4a1e60812c9 100644
--- a/src/librustc_metadata/encoder.rs
+++ b/src/librustc_metadata/encoder.rs
@@ -730,7 +730,6 @@ impl<'a, 'tcx> EncodeContext<'a, 'tcx> {
                     unsafety: trait_def.unsafety,
                     paren_sugar: trait_def.paren_sugar,
                     has_default_impl: tcx.trait_has_default_impl(def_id),
-                    trait_ref: self.lazy(&trait_def.trait_ref),
                     super_predicates: self.lazy(&tcx.item_super_predicates(def_id)),
                 };
 
diff --git a/src/librustc_metadata/schema.rs b/src/librustc_metadata/schema.rs
index 32e89f64f0e..c74c8c58ab8 100644
--- a/src/librustc_metadata/schema.rs
+++ b/src/librustc_metadata/schema.rs
@@ -278,7 +278,6 @@ pub struct TraitData<'tcx> {
     pub unsafety: hir::Unsafety,
     pub paren_sugar: bool,
     pub has_default_impl: bool,
-    pub trait_ref: Lazy<ty::TraitRef<'tcx>>,
     pub super_predicates: Lazy<ty::GenericPredicates<'tcx>>,
 }
 
diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs
index bb7b6253300..786106e805f 100644
--- a/src/librustc_typeck/astconv.rs
+++ b/src/librustc_typeck/astconv.rs
@@ -91,7 +91,7 @@ pub trait AstConv<'gcx, 'tcx> {
     /// Returns the `TraitDef` for a given trait. This allows you to
     /// figure out the set of type parameters defined on the trait.
     fn get_trait_def(&self, span: Span, id: DefId)
-                     -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>;
+                     -> Result<&'tcx ty::TraitDef, ErrorReported>;
 
     /// Ensure that the super-predicates for the trait with the given
     /// id are available and also for the transitive set of
diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs
index f2dcc174d55..2e66f6290a0 100644
--- a/src/librustc_typeck/check/method/mod.rs
+++ b/src/librustc_typeck/check/method/mod.rs
@@ -192,13 +192,6 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
                m_name,
                trait_def_id);
 
-        let trait_def = self.tcx.lookup_trait_def(trait_def_id);
-
-        if let Some(ref input_types) = opt_input_types {
-            assert_eq!(trait_def.generics.types.len() - 1, input_types.len());
-        }
-        assert!(trait_def.generics.regions.is_empty());
-
         // Construct a trait-reference `self_ty : Trait<input_tys>`
         let substs = Substs::for_item(self.tcx,
                                       trait_def_id,
diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs
index 0c4e5e4fa0d..2a17867fbd5 100644
--- a/src/librustc_typeck/check/mod.rs
+++ b/src/librustc_typeck/check/mod.rs
@@ -1040,7 +1040,7 @@ fn report_forbidden_specialization<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
 }
 
 fn check_specialization_validity<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
-                                           trait_def: &ty::TraitDef<'tcx>,
+                                           trait_def: &ty::TraitDef,
                                            impl_id: DefId,
                                            impl_item: &hir::ImplItem)
 {
@@ -1400,7 +1400,7 @@ impl<'a, 'gcx, 'tcx> AstConv<'gcx, 'tcx> for FnCtxt<'a, 'gcx, 'tcx> {
     }
 
     fn get_trait_def(&self, _: Span, id: DefId)
-                     -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
+                     -> Result<&'tcx ty::TraitDef, ErrorReported>
     {
         Ok(self.tcx().lookup_trait_def(id))
     }
diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs
index b6d0ff03a07..fd5d922f935 100644
--- a/src/librustc_typeck/check/wfcheck.rs
+++ b/src/librustc_typeck/check/wfcheck.rs
@@ -290,12 +290,7 @@ impl<'ccx, 'gcx> CheckTypeWellFormedVisitor<'ccx, 'gcx> {
                 }
             });
 
-        let trait_def = self.tcx().lookup_trait_def(trait_def_id);
-
-        let has_ty_params =
-            trait_def.generics
-                      .types
-                      .len() > 1;
+        let has_ty_params = self.tcx().item_generics(trait_def_id).types.len() > 1;
 
         // We use an if-else here, since the generics will also trigger
         // an extraneous error message when we find predicates like
diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs
index 011c8262518..c749e1cf842 100644
--- a/src/librustc_typeck/collect.rs
+++ b/src/librustc_typeck/collect.rs
@@ -329,20 +329,21 @@ impl<'a,'tcx> CrateCtxt<'a,'tcx> {
     }
 
     /// Loads the trait def for a given trait, returning ErrorReported if a cycle arises.
-    fn get_trait_def(&self, trait_id: DefId)
-                     -> &'tcx ty::TraitDef<'tcx>
+    fn get_trait_def(&self, def_id: DefId)
+                     -> &'tcx ty::TraitDef
     {
         let tcx = self.tcx;
 
-        if let Some(trait_id) = tcx.map.as_local_node_id(trait_id) {
+        if let Some(trait_id) = tcx.map.as_local_node_id(def_id) {
             let item = match tcx.map.get(trait_id) {
                 hir_map::NodeItem(item) => item,
                 _ => bug!("get_trait_def({:?}): not an item", trait_id)
             };
 
+            generics_of_def_id(self, def_id);
             trait_def_of_item(self, &item)
         } else {
-            tcx.lookup_trait_def(trait_id)
+            tcx.lookup_trait_def(def_id)
         }
     }
 
@@ -392,7 +393,7 @@ impl<'a, 'tcx> AstConv<'tcx, 'tcx> for ItemCtxt<'a, 'tcx> {
     }
 
     fn get_trait_def(&self, span: Span, id: DefId)
-                     -> Result<&'tcx ty::TraitDef<'tcx>, ErrorReported>
+                     -> Result<&'tcx ty::TraitDef, ErrorReported>
     {
         self.ccx.cycle_check(span, AstConvRequest::GetTraitDef(id), || {
             Ok(self.ccx.get_trait_def(id))
@@ -716,6 +717,7 @@ fn ensure_no_ty_param_bounds(ccx: &CrateCtxt,
 fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
     let tcx = ccx.tcx;
     debug!("convert: item {} with id {}", it.name, it.id);
+    let def_id = ccx.tcx.map.local_def_id(it.id);
     match it.node {
         // These don't define types.
         hir::ItemExternCrate(_) | hir::ItemUse(..) | hir::ItemMod(_) => {
@@ -726,7 +728,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
             }
         }
         hir::ItemEnum(ref enum_definition, _) => {
-            let def_id = ccx.tcx.map.local_def_id(it.id);
             let ty = type_of_def_id(ccx, def_id);
             let generics = generics_of_def_id(ccx, def_id);
             let predicates = predicates_of_item(ccx, it);
@@ -756,7 +757,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
                       _) => {
             // Create generics from the generics specified in the impl head.
             debug!("convert: ast_generics={:?}", generics);
-            let def_id = ccx.tcx.map.local_def_id(it.id);
             generics_of_def_id(ccx, def_id);
             let mut ty_predicates =
                 ty_generic_predicates(ccx, generics, None, vec![], false);
@@ -786,8 +786,8 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
             tcx.predicates.borrow_mut().insert(def_id, ty_predicates.clone());
         },
         hir::ItemTrait(.., ref trait_items) => {
-            let trait_def = trait_def_of_item(ccx, it);
-            let def_id = trait_def.trait_ref.def_id;
+            generics_of_def_id(ccx, def_id);
+            trait_def_of_item(ccx, it);
             let _: Result<(), ErrorReported> = // any error is already reported, can ignore
                 ccx.ensure_super_predicates(it.span, def_id);
             convert_trait_predicates(ccx, it);
@@ -838,7 +838,6 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
         },
         hir::ItemStruct(ref struct_def, _) |
         hir::ItemUnion(ref struct_def, _) => {
-            let def_id = ccx.tcx.map.local_def_id(it.id);
             let ty = type_of_def_id(ccx, def_id);
             let generics = generics_of_def_id(ccx, def_id);
             let predicates = predicates_of_item(ccx, it);
@@ -855,13 +854,11 @@ fn convert_item(ccx: &CrateCtxt, it: &hir::Item) {
         },
         hir::ItemTy(_, ref generics) => {
             ensure_no_ty_param_bounds(ccx, it.span, generics, "type");
-            let def_id = ccx.tcx.map.local_def_id(it.id);
             type_of_def_id(ccx, def_id);
             generics_of_def_id(ccx, def_id);
             predicates_of_item(ccx, it);
         },
         _ => {
-            let def_id = ccx.tcx.map.local_def_id(it.id);
             type_of_def_id(ccx, def_id);
             generics_of_def_id(ccx, def_id);
             predicates_of_item(ccx, it);
@@ -1155,10 +1152,15 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
         // In-scope when converting the superbounds for `Trait` are
         // that `Self:Trait` as well as any bounds that appear on the
         // generic types:
-        let trait_def = trait_def_of_item(ccx, item);
+        generics_of_def_id(ccx, trait_def_id);
+        trait_def_of_item(ccx, item);
+        let trait_ref = ty::TraitRef {
+            def_id: trait_def_id,
+            substs: Substs::identity_for_item(tcx, trait_def_id)
+        };
         let self_predicate = ty::GenericPredicates {
             parent: None,
-            predicates: vec![trait_def.trait_ref.to_predicate()]
+            predicates: vec![trait_ref.to_predicate()]
         };
         let scope = &(generics, &self_predicate);
 
@@ -1203,54 +1205,41 @@ fn ensure_super_predicates_step(ccx: &CrateCtxt,
     def_ids
 }
 
-fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
-                               it: &hir::Item)
-                               -> &'tcx ty::TraitDef<'tcx>
-{
+fn trait_def_of_item<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) -> &'tcx ty::TraitDef {
     let def_id = ccx.tcx.map.local_def_id(it.id);
     let tcx = ccx.tcx;
 
-    if let Some(def) = tcx.trait_defs.borrow().get(&def_id) {
-        return def.clone();
-    }
+    tcx.trait_defs.memoize(def_id, || {
+        let unsafety = match it.node {
+            hir::ItemTrait(unsafety, ..) => unsafety,
+            _ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
+        };
 
-    let (unsafety, generics) = match it.node {
-        hir::ItemTrait(unsafety, ref generics, _, _) => {
-            (unsafety, generics)
+        let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
+        if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
+            let mut err = ccx.tcx.sess.struct_span_err(
+                it.span,
+                "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
+                which traits can use parenthetical notation");
+            help!(&mut err,
+                "add `#![feature(unboxed_closures)]` to \
+                the crate attributes to use it");
+            err.emit();
         }
-        _ => span_bug!(it.span, "trait_def_of_item invoked on non-trait"),
-    };
-
-    let paren_sugar = tcx.has_attr(def_id, "rustc_paren_sugar");
-    if paren_sugar && !ccx.tcx.sess.features.borrow().unboxed_closures {
-        let mut err = ccx.tcx.sess.struct_span_err(
-            it.span,
-            "the `#[rustc_paren_sugar]` attribute is a temporary means of controlling \
-             which traits can use parenthetical notation");
-        help!(&mut err,
-            "add `#![feature(unboxed_closures)]` to \
-             the crate attributes to use it");
-        err.emit();
-    }
-
-    let ty_generics = generics_of_def_id(ccx, def_id);
-    let substs = mk_item_substs(&ccx.icx(generics), it.span, def_id);
-
-    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,
-                                      def_path_hash);
 
-    tcx.intern_trait_def(trait_def)
+        let def_path_hash = tcx.def_path(def_id).deterministic_hash(tcx);
+        tcx.alloc_trait_def(ty::TraitDef::new(def_id, unsafety, paren_sugar, def_path_hash))
+    })
 }
 
 fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item) {
     let tcx = ccx.tcx;
-    let trait_def = trait_def_of_item(ccx, it);
 
     let def_id = ccx.tcx.map.local_def_id(it.id);
 
+    generics_of_def_id(ccx, def_id);
+    trait_def_of_item(ccx, it);
+
     let (generics, items) = match it.node {
         hir::ItemTrait(_, ref generics, _, ref items) => (generics, items),
         ref s => {
@@ -1272,7 +1261,11 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
 
     // Add in a predicate that `Self:Trait` (where `Trait` is the
     // current trait).  This is needed for builtin bounds.
-    let self_predicate = trait_def.trait_ref.to_poly_trait_ref().to_predicate();
+    let trait_ref = ty::TraitRef {
+        def_id: def_id,
+        substs: Substs::identity_for_item(tcx, def_id)
+    };
+    let self_predicate = trait_ref.to_poly_trait_ref().to_predicate();
     base_predicates.push(self_predicate);
 
     // add in the explicit where-clauses
@@ -1282,7 +1275,7 @@ fn convert_trait_predicates<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>, it: &hir::Item)
     let assoc_predicates = predicates_for_associated_types(ccx,
                                                            generics,
                                                            &trait_predicates,
-                                                           trait_def.trait_ref,
+                                                           trait_ref,
                                                            items);
     trait_predicates.predicates.extend(assoc_predicates);
 
@@ -1581,7 +1574,10 @@ fn type_of_def_id<'a, 'tcx>(ccx: &CrateCtxt<'a, 'tcx>,
             NodeExpr(&hir::Expr { node: hir::ExprClosure(..), .. }) => {
                 ccx.tcx.mk_closure(def_id, Substs::for_item(
                     ccx.tcx, def_id,
-                    |def, _| ccx.tcx.mk_region(def.to_early_bound_region()),
+                    |def, _| {
+                        let region = def.to_early_bound_region_data();
+                        ccx.tcx.mk_region(ty::ReEarlyBound(region))
+                    },
                     |def, _| ccx.tcx.mk_param_from_def(def)
                 ))
             }
@@ -2095,7 +2091,5 @@ pub fn mk_item_substs<'gcx: 'tcx, 'tcx>(astconv: &AstConv<'gcx, 'tcx>,
         bug!("ErrorReported returned, but no errors reports?")
     }
 
-    Substs::for_item(tcx, def_id,
-                     |def, _| tcx.mk_region(def.to_early_bound_region()),
-                     |def, _| tcx.mk_param_from_def(def))
+    Substs::identity_for_item(tcx, def_id)
 }
diff --git a/src/librustc_typeck/variance/constraints.rs b/src/librustc_typeck/variance/constraints.rs
index 686d1a4a771..823c6e2744f 100644
--- a/src/librustc_typeck/variance/constraints.rs
+++ b/src/librustc_typeck/variance/constraints.rs
@@ -97,9 +97,13 @@ impl<'a, 'tcx, 'v> ItemLikeVisitor<'v> for ConstraintContext<'a, 'tcx> {
                 }
             }
             hir::ItemTrait(..) => {
-                let trait_def = tcx.lookup_trait_def(did);
-                self.add_constraints_from_trait_ref(&trait_def.generics,
-                                                    trait_def.trait_ref,
+                let generics = tcx.item_generics(did);
+                let trait_ref = ty::TraitRef {
+                    def_id: did,
+                    substs: Substs::identity_for_item(tcx, did)
+                };
+                self.add_constraints_from_trait_ref(generics,
+                                                    trait_ref,
                                                     self.invariant);
             }
 
@@ -279,7 +283,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
                trait_ref,
                variance);
 
-        let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id);
+        let trait_generics = self.tcx().item_generics(trait_ref.def_id);
 
         // This edge is actually implied by the call to
         // `lookup_trait_def`, but I'm trying to be future-proof. See
@@ -288,8 +292,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
         self.add_constraints_from_substs(generics,
                                          trait_ref.def_id,
-                                         &trait_def.generics.types,
-                                         &trait_def.generics.regions,
+                                         &trait_generics.types,
+                                         &trait_generics.regions,
                                          trait_ref.substs,
                                          variance);
     }
@@ -356,7 +360,7 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
             ty::TyProjection(ref data) => {
                 let trait_ref = &data.trait_ref;
-                let trait_def = self.tcx().lookup_trait_def(trait_ref.def_id);
+                let trait_generics = self.tcx().item_generics(trait_ref.def_id);
 
                 // This edge is actually implied by the call to
                 // `lookup_trait_def`, but I'm trying to be future-proof. See
@@ -365,8 +369,8 @@ impl<'a, 'tcx> ConstraintContext<'a, 'tcx> {
 
                 self.add_constraints_from_substs(generics,
                                                  trait_ref.def_id,
-                                                 &trait_def.generics.types,
-                                                 &trait_def.generics.regions,
+                                                 &trait_generics.types,
+                                                 &trait_generics.regions,
                                                  trait_ref.substs,
                                                  variance);
             }
diff --git a/src/librustdoc/clean/inline.rs b/src/librustdoc/clean/inline.rs
index e3274611e5b..d12e0ae6ddb 100644
--- a/src/librustdoc/clean/inline.rs
+++ b/src/librustdoc/clean/inline.rs
@@ -151,14 +151,13 @@ pub fn record_extern_fqn(cx: &DocContext, did: DefId, kind: clean::TypeKind) {
 }
 
 pub fn build_external_trait(cx: &DocContext, did: DefId) -> clean::Trait {
-    let def = cx.tcx.lookup_trait_def(did);
     let trait_items = cx.tcx.associated_items(did).map(|item| item.clean(cx)).collect();
     let predicates = cx.tcx.item_predicates(did);
-    let generics = (def.generics, &predicates).clean(cx);
+    let generics = (cx.tcx.item_generics(did), &predicates).clean(cx);
     let generics = filter_non_trait_generics(did, generics);
     let (generics, supertrait_bounds) = separate_supertrait_bounds(generics);
     clean::Trait {
-        unsafety: def.unsafety,
+        unsafety: cx.tcx.lookup_trait_def(did).unsafety,
         generics: generics,
         items: trait_items,
         bounds: supertrait_bounds,
diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs
index e233613ee62..5538b78c005 100644
--- a/src/librustdoc/clean/mod.rs
+++ b/src/librustdoc/clean/mod.rs
@@ -1407,9 +1407,8 @@ impl<'tcx> Clean<Item> for ty::AssociatedItem {
                     // are actually located on the trait/impl itself, so we need to load
                     // all of the generics from there and then look for bounds that are
                     // applied to this associated type in question.
-                    let def = cx.tcx.lookup_trait_def(did);
                     let predicates = cx.tcx.item_predicates(did);
-                    let generics = (def.generics, &predicates).clean(cx);
+                    let generics = (cx.tcx.item_generics(did), &predicates).clean(cx);
                     generics.where_predicates.iter().filter_map(|pred| {
                         let (name, self_type, trait_, bounds) = match *pred {
                             WherePredicate::BoundPredicate {