From 3f338eed99265fe5e9a167abb2e1f4a7ff2ea101 Mon Sep 17 00:00:00 2001 From: Eduard-Mihai Burtescu Date: Fri, 25 Nov 2016 02:29:26 +0200 Subject: [PATCH] rustc: remove type information from TraitDef. --- src/librustc/middle/cstore.rs | 4 +- src/librustc/traits/error_reporting.rs | 6 +- src/librustc/traits/object_safety.rs | 16 ++- .../traits/specialize/specialization_graph.rs | 14 +-- src/librustc/ty/context.rs | 16 +-- src/librustc/ty/maps.rs | 2 +- src/librustc/ty/mod.rs | 6 +- src/librustc/ty/subst.rs | 8 ++ src/librustc/ty/trait_def.rs | 39 +++---- src/librustc/util/ppaux.rs | 7 +- src/librustc_metadata/cstore_impl.rs | 2 +- src/librustc_metadata/decoder.rs | 7 +- src/librustc_metadata/encoder.rs | 1 - src/librustc_metadata/schema.rs | 1 - src/librustc_typeck/astconv.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 7 -- src/librustc_typeck/check/mod.rs | 4 +- src/librustc_typeck/check/wfcheck.rs | 7 +- src/librustc_typeck/collect.rs | 104 +++++++++--------- src/librustc_typeck/variance/constraints.rs | 22 ++-- src/librustdoc/clean/inline.rs | 5 +- src/librustdoc/clean/mod.rs | 3 +- 22 files changed, 123 insertions(+), 160 deletions(-) diff --git a/src/librustc/middle/cstore.rs b/src/librustc/middle/cstore.rs index d055506a38226..12557fe4301a5 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; - 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; fn inherent_implementations_for_type(&self, def_id: DefId) -> Vec; @@ -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 { 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 21009711cb18a..f560308abe0d1 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::>(); diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index 0681be129b67e..ceee6c236e4e3 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 5a6809f1fad68..a41523f2def76 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, } -impl<'a, 'tcx> Iterator for Ancestors<'a, 'tcx> { +impl<'a> Iterator for Ancestors<'a> { type Item = Node; fn next(&mut self) -> Option { 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 NodeItem { } } -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 ea81c85ba6a53..025b35100a738 100644 --- a/src/librustc/ty/context.rs +++ b/src/librustc/ty/context.rs @@ -66,7 +66,7 @@ pub struct CtxtArenas<'tcx> { // references generics: TypedArena>, - trait_def: TypedArena>, + trait_def: TypedArena, adt_def: TypedArena>, mir: TypedArena>>, } @@ -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 bf0445858794e..1fc1c32c2d5c8 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> } dep_map_ty! { ImplTraitRefs: ItemSignature(DefId) -> Option> } -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> } dep_map_ty! { InherentImpls: InherentImpls(DefId) -> Vec } diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 9a92e9e70feb4..288ca751bd498 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 41fcb09fb2dc7..d6f61a12a3c6e 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>; 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 fd81065e61d49..c6d862b23bd5e 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 { 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(&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 d04825d560444..641b1b548806d 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 573b2f6d2a60c..624350d84db78 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 d5b08927a06f1..d75bab9dc5a2b 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 4839c409335ea..4a1e60812c9a4 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 32e89f64f0ec1..c74c8c58ab8b6 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>, pub super_predicates: Lazy>, } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index bb7b62533001d..786106e805f39 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 f2dcc174d55bb..2e66f6290a022 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` 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 0c4e5e4fa0dfc..2a17867fbd54b 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 b6d0ff03a07ab..fd5d922f935e4 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 011c82625186f..c749e1cf84291 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 686d1a4a7716d..823c6e2744fe8 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 e3274611e5bff..d12e0ae6ddbeb 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 e233613ee629e..5538b78c00548 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1407,9 +1407,8 @@ impl<'tcx> Clean 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 {