]> git.lizzy.rs Git - rust.git/commitdiff
rustc: remove type information from TraitDef.
authorEduard-Mihai Burtescu <edy.burt@gmail.com>
Fri, 25 Nov 2016 00:29:26 +0000 (02:29 +0200)
committerEduard-Mihai Burtescu <edy.burt@gmail.com>
Tue, 29 Nov 2016 19:24:26 +0000 (21:24 +0200)
22 files changed:
src/librustc/middle/cstore.rs
src/librustc/traits/error_reporting.rs
src/librustc/traits/object_safety.rs
src/librustc/traits/specialize/specialization_graph.rs
src/librustc/ty/context.rs
src/librustc/ty/maps.rs
src/librustc/ty/mod.rs
src/librustc/ty/subst.rs
src/librustc/ty/trait_def.rs
src/librustc/util/ppaux.rs
src/librustc_metadata/cstore_impl.rs
src/librustc_metadata/decoder.rs
src/librustc_metadata/encoder.rs
src/librustc_metadata/schema.rs
src/librustc_typeck/astconv.rs
src/librustc_typeck/check/method/mod.rs
src/librustc_typeck/check/mod.rs
src/librustc_typeck/check/wfcheck.rs
src/librustc_typeck/collect.rs
src/librustc_typeck/variance/constraints.rs
src/librustdoc/clean/inline.rs
src/librustdoc/clean/mod.rs

index d055506a38226b8277316b9a3f4a729544cac274..12557fe4301a577885b8be3345c397f41232dd6b 100644 (file)
@@ -277,7 +277,7 @@ fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
     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 @@ fn item_super_predicates<'a>(&self, tcx: TyCtxt<'a, 'tcx, 'tcx>, def: DefId)
     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") }
index 21009711cb18ae61a17cf486142d75a5d6b609f8..f560308abe0d11751cb8a40c1ca778e8e0f1f9b4 100644 (file)
@@ -244,11 +244,11 @@ fn on_unimplemented_note(&self,
         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>>();
index 0681be129b67e9cbd3983ad8202065c2365fa566..ceee6c236e4e3dba250c6364d3a5ef6e5fc796ab 100644 (file)
@@ -21,7 +21,8 @@
 
 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 @@ fn object_safety_violations_for_trait(self, trait_def_id: DefId)
     }
 
     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 @@ fn contains_illegal_self_type_reference(self,
 
                     // 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());
                     }
 
index 5a6809f1fad6829824078529e8d4b106f492645e..a41523f2def76385d1cc323bf6ff103781ac4c6a 100644 (file)
@@ -297,18 +297,18 @@ pub fn def_id(&self) -> DefId {
     }
 }
 
-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 @@ pub fn map<U, F: FnOnce(T) -> U>(self, f: F) -> NodeItem<U> {
     }
 }
 
-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 @@ pub fn defs(self, tcx: TyCtxt<'a, 'gcx, 'tcx>, name: Name, kind: ty::AssociatedK
 
 /// 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)),
index ea81c85ba6a53f96fe1280de57646157bb560dbf..025b35100a73889099f5f6eac95b42701c639b05 100644 (file)
@@ -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 @@ pub fn alloc_mir(self, mir: Mir<'gcx>) -> &'gcx RefCell<Mir<'gcx>> {
         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)
     }
 
index bf0445858794e3ec2f4fd0a09d3afc805d484af1..1fc1c32c2d5c86b52b088ede490c2be093b2f3bd 100644 (file)
@@ -39,7 +39,7 @@ fn to_dep_node(key: &$key) -> DepNode<DefId> { DepNode::$node_name(*key) }
 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> }
index 9a92e9e70feb4e65681b36c07e59db7ada659871..288ca751bd498a523b52509ad81822fd5c265b3c 100644 (file)
@@ -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 @@ pub fn item_type(self, did: DefId) -> Ty<'gcx> {
     }
 
     /// 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))
index 41fcb09fb2dc7ef2c3eb324e7679900b1122d0fd..d6f61a12a3c6eb2ca8ad84ab7f6ec6d0303e33aa 100644 (file)
@@ -165,6 +165,14 @@ fn decode<D: Decoder>(d: &mut D) -> Result<Kind<'tcx>, D::Error> {
 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
index fd81065e61d499f3590272c152ac8f5ad7dbec44..c6d862b23bd5e393fc2bc67da607d37c730e7e7d 100644 (file)
@@ -19,7 +19,9 @@
 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 @@ pub fn new(unsafety: hir::Unsafety,
         }
     }
 
-    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 @@ pub fn set_object_safety(&self, is_safe: bool) {
     }
 
     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 @@ pub fn add_impl_for_specialization(&self,
             .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 @@ pub fn for_each_relevant_impl<F: FnMut(DefId)>(&self,
     {
         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);
index d04825d560444facbc47d19960a4fb9b0b26f306..641b1b548806d93fccd2f158cae03e1bce7d6006 100644 (file)
@@ -432,10 +432,11 @@ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
     }
 }
 
-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))
+        })
     }
 }
 
index 573b2f6d2a60cd9c500ecc820f9954dd3fc6785d..624350d84db783ff1585c9479442af8fd9d14582 100644 (file)
@@ -110,7 +110,7 @@ fn item_attrs(&self, def_id: DefId) -> Vec<ast::Attribute>
         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)
index d5b08927a06f10402ee549646a2733a71543279c..d75bab9dc5a2bbb40b476b0a2c2c6a0e26f0b991 100644 (file)
@@ -531,16 +531,15 @@ pub fn get_def(&self, index: DefIndex) -> Option<Def> {
     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))
     }
 
index 4839c409335ea8fb5dfbba579cbfca491b10bfd8..4a1e60812c9a44c7b1d8e3aed39fdd16beac9dbc 100644 (file)
@@ -730,7 +730,6 @@ fn encode_info_for_item(&mut self, (def_id, item): (DefId, &'tcx hir::Item)) ->
                     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)),
                 };
 
index 32e89f64f0ec1516b2049e8f5a46bafefde83342..c74c8c58ab8b6119f0eed28dc865c3640112c479 100644 (file)
@@ -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>>,
 }
 
index bb7b62533001db17b633a294ca0f93615511af6e..786106e805f3949845a4186ce530b7488c68b169 100644 (file)
@@ -91,7 +91,7 @@ fn get_generics(&self, span: Span, id: DefId)
     /// 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
index f2dcc174d55bbdbae342a63bb2e027ba8ca2e259..2e66f6290a022deb523097ab40adfbc17bdadd20 100644 (file)
@@ -192,13 +192,6 @@ pub fn lookup_method_in_trait_adjusted(&self,
                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,
index 0c4e5e4fa0dfc4d88a1a99370d8ea079ea1ddbb8..2a17867fbd54b6ac0b9490847ee67c74e8164233 100644 (file)
@@ -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 @@ fn get_item_type(&self, _: Span, id: DefId) -> Result<Ty<'tcx>, ErrorReported>
     }
 
     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))
     }
index b6d0ff03a07abb87953446b1b6ba714b5563cbdf..fd5d922f935e499fc4ff224028a668eaac25ffb6 100644 (file)
@@ -290,12 +290,7 @@ fn check_auto_trait(&mut self, trait_def_id: DefId, span: Span) {
                 }
             });
 
-        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
index 011c82625186f338320451ed8f8758914289ed96..c749e1cf8429119a5a25715b83d15bd7b14a600a 100644 (file)
@@ -329,20 +329,21 @@ fn report_cycle(&self,
     }
 
     /// 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 @@ fn get_item_type(&self, span: Span, id: DefId) -> Result<Ty<'tcx>, ErrorReported
     }
 
     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)
 }
index 686d1a4a7716d823e38a204e5346d68c7b85d2aa..823c6e2744fe872f70eb758e422e0056ff5312d5 100644 (file)
@@ -97,9 +97,13 @@ fn visit_item(&mut self, item: &hir::Item) {
                 }
             }
             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 @@ fn add_constraints_from_trait_ref(&mut self,
                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 @@ fn add_constraints_from_trait_ref(&mut self,
 
         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 @@ fn add_constraints_from_ty(&mut self,
 
             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 @@ fn add_constraints_from_ty(&mut self,
 
                 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);
             }
index e3274611e5bff3ee30ba50c61b825865e20e7dfa..d12e0ae6ddbebdce8e630d0e6f0b27d4eefe0cca 100644 (file)
@@ -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,
index e233613ee629e8844652371a4fd86ec96ec82f99..5538b78c00548375347c7b78767485d0ae5875d9 100644 (file)
@@ -1407,9 +1407,8 @@ fn clean(&self, cx: &DocContext) -> Item {
                     // 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 {