diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index c7f0979766c..62da6be5b21 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -735,7 +735,7 @@ fn hash_stable(&self, hasher: &mut StableHasher) { let ty::Generics { parent, - ref parent_parameters, + ref parent_count, ref parameters, // Reverse map to each `TypeParameterDef`'s `index` field, from @@ -746,7 +746,7 @@ fn hash_stable(&self, } = *self; parent.hash_stable(hcx, hasher); - parent_parameters.hash_stable(hcx, hasher); + parent_count.hash_stable(hcx, hasher); parameters.hash_stable(hcx, hasher); has_self.hash_stable(hcx, hasher); has_late_bound_regions.hash_stable(hcx, hasher); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index f32316ac547..8f5ec3aae8a 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -784,7 +784,7 @@ pub fn index(&self) -> u32 { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct Generics { pub parent: Option, - pub parent_parameters: Vec, + pub parent_count: usize, pub parameters: Vec, /// Reverse map to each `TypeParameterDef`'s `index` field @@ -795,16 +795,12 @@ pub struct Generics { } impl<'a, 'gcx, 'tcx> Generics { - pub fn parent_count(&self) -> usize { - self.parent_parameters.iter().map(|&x| x as usize).sum() - } - pub fn own_count(&self) -> usize { self.parameters.len() } pub fn count(&self) -> usize { - self.parent_count() + self.own_count() + self.parent_count + self.own_count() } pub fn lifetimes(&self) -> Vec<&RegionParameterDef> { @@ -827,12 +823,16 @@ pub fn types(&self) -> Vec<&TypeParameterDef> { }).collect() } - pub fn parent_lifetimes(&self) -> u32 { - self.parent_parameters[0] - } - - pub fn parent_types(&self) -> u32 { - self.parent_parameters[1] + pub fn has_type_parameters(&self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> bool { + if self.types().len() != 0 { + return true; + } + if let Some(parent_def_id) = self.parent { + let parent = tcx.generics_of(parent_def_id); + parent.has_type_parameters(tcx) + } else { + false + } } pub fn region_param(&'tcx self, @@ -840,7 +840,7 @@ pub fn region_param(&'tcx self, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx RegionParameterDef { - if let Some(index) = param.index.checked_sub(self.parent_count() as u32) { + if let Some(index) = param.index.checked_sub(self.parent_count as u32) { // We're currently assuming that lifetimes precede other generic parameters. match self.parameters[index as usize - self.has_self as usize] { ty::GenericParameterDef::Lifetime(ref lt) => lt, @@ -857,7 +857,7 @@ pub fn type_param(&'tcx self, param: &ParamTy, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &TypeParameterDef { - if let Some(idx) = param.idx.checked_sub(self.parent_count() as u32) { + if let Some(idx) = param.idx.checked_sub(self.parent_count as u32) { // non-Self type parameters are always offset by exactly // `self.regions.len()`. In the absence of a Self, this is obvious, // but even in the presence of a `Self` we just have to "compensate" diff --git a/src/librustc/ty/sty.rs b/src/librustc/ty/sty.rs index f0a7ce54971..c1e3153c461 100644 --- a/src/librustc/ty/sty.rs +++ b/src/librustc/ty/sty.rs @@ -292,7 +292,7 @@ impl<'tcx> ClosureSubsts<'tcx> { /// ordering. fn split(self, def_id: DefId, tcx: TyCtxt<'_, '_, '_>) -> SplitClosureSubsts<'tcx> { let generics = tcx.generics_of(def_id); - let parent_len = generics.parent_count(); + let parent_len = generics.parent_count; SplitClosureSubsts { closure_kind_ty: self.substs.type_at(parent_len), closure_sig_ty: self.substs.type_at(parent_len + 1), diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index 7e580e9333f..9ebffa4c744 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -929,10 +929,9 @@ fn encode_info_for_impl_item(&mut self, def_id: DefId) -> Entry<'tcx> { hir::ImplItemKind::Const(..) => true, hir::ImplItemKind::Method(ref sig, _) => { let generics = self.tcx.generics_of(def_id); - let types = generics.parent_types() as usize + generics.types().len(); - let needs_inline = - (types > 0 || tcx.trans_fn_attrs(def_id).requests_inline()) - && !self.metadata_output_only(); + let needs_inline = (generics.has_type_parameters(self.tcx) || + tcx.trans_fn_attrs(def_id).requests_inline()) && + !self.metadata_output_only(); let is_const_fn = sig.constness == hir::Constness::Const; let always_encode_mir = self.tcx.sess.opts.debugging_opts.always_encode_mir; needs_inline || is_const_fn || always_encode_mir diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index bfdf81588af..ecdd6b358cd 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1076,7 +1076,7 @@ fn push_extra_entry_roots(&mut self) { fn item_has_type_parameters<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: DefId) -> bool { let generics = tcx.generics_of(def_id); - generics.parent_types() as usize + generics.types().len() > 0 + generics.has_type_parameters(tcx) } fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index 4286946599a..ef3f81cfc5c 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -1139,7 +1139,7 @@ pub fn impl_trait_ty_to_ty(&self, def_id: DefId, lifetimes: &[hir::Lifetime]) -> } debug!("impl_trait_ty_to_ty: substs from parent = {:?}", substs); } - assert_eq!(substs.len(), generics.parent_count()); + assert_eq!(substs.len(), generics.parent_count); // Fill in our own generics with the resolved lifetimes assert_eq!(lifetimes.len(), generics.own_count()); diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 3accb51f308..ed4fb7ba939 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -314,7 +314,7 @@ fn instantiate_method_substs(&mut self, // Create subst for early-bound lifetime parameters, combining // parameters from the type and those from the method. - assert_eq!(method_generics.parent_count(), parent_substs.len()); + assert_eq!(method_generics.parent_count, parent_substs.len()); let provided = &segment.parameters; Substs::for_item(self.tcx, pick.item.def_id, |def, _| { let i = def.index as usize; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index d3335fdd980..513bc6931ec 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1378,8 +1378,7 @@ fn xform_method_sig(&self, // method yet. So create fresh variables here for those too, // if there are any. let generics = self.tcx.generics_of(method); - assert_eq!(substs.regions().count(), generics.parent_lifetimes() as usize); - assert_eq!(substs.types().count(), generics.parent_types() as usize); + assert_eq!(substs.len(), generics.parent_count as usize); // Erase any late-bound regions from the method and substitute // in the values from the substitution. diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 1faf1f7e882..0c875e704c6 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4751,7 +4751,7 @@ pub fn instantiate_value_path(&self, let (fn_start, has_self) = match (type_segment, fn_segment) { (_, Some((_, generics))) => { - (generics.parent_count(), generics.has_self) + (generics.parent_count, generics.has_self) } (Some((_, generics)), None) => { (generics.own_count(), generics.has_self) diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index bb308668869..ffbbb3b1fae 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -876,13 +876,12 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let has_self = opt_self.is_some(); let mut parent_has_self = false; let mut own_start = has_self as u32; - let (parent_regions, parent_types) = parent_def_id.map_or((0, 0), |def_id| { + let parent_count = parent_def_id.map_or(0, |def_id| { let generics = tcx.generics_of(def_id); assert_eq!(has_self, false); parent_has_self = generics.has_self; own_start = generics.count() as u32; - (generics.parent_lifetimes() + generics.lifetimes().len() as u32, - generics.parent_types() + generics.types().len() as u32) + generics.parent_count + generics.parameters.len() }); let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); @@ -971,7 +970,6 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .map(|param| (param.def_id, param.index)) .collect(); - let parent_parameters = vec![parent_regions, parent_types]; let lifetimes: Vec = regions.into_iter().map(|lt| ty::GenericParameterDef::Lifetime(lt)).collect(); let types: Vec = @@ -980,7 +978,7 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx.alloc_generics(ty::Generics { parent: parent_def_id, - parent_parameters, + parent_count, parameters, type_param_to_index, has_self: has_self || parent_has_self, @@ -1395,7 +1393,7 @@ pub fn explicit_predicates_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; let generics = tcx.generics_of(def_id); - let parent_count = generics.parent_count() as u32; + let parent_count = generics.parent_count as u32; let has_own_self = generics.has_self && parent_count == 0; let mut predicates = vec![];