From fe0c119e7da2e9b068dd54bb88e8acb23d31bfa4 Mon Sep 17 00:00:00 2001 From: varkor Date: Thu, 8 Mar 2018 10:39:31 +0000 Subject: [PATCH] Consolidate ty::Generics --- src/librustc/hir/lowering.rs | 2 +- src/librustc/ich/impls_ty.rs | 17 ++--- src/librustc/infer/anon_types/mod.rs | 2 +- src/librustc/middle/resolve_lifetime.rs | 2 +- src/librustc/traits/error_reporting.rs | 2 +- src/librustc/traits/object_safety.rs | 2 +- src/librustc/traits/on_unimplemented.rs | 4 +- src/librustc/ty/mod.rs | 73 +++++++++++++++++--- src/librustc/ty/subst.rs | 31 +++++---- src/librustc/util/ppaux.rs | 14 ++-- src/librustc_metadata/encoder.rs | 2 +- src/librustc_mir/monomorphize/collector.rs | 4 +- src/librustc_mir/transform/check_unsafety.rs | 2 +- src/librustc_privacy/lib.rs | 4 +- src/librustc_trans/debuginfo/mod.rs | 2 +- src/librustc_typeck/astconv.rs | 8 +-- src/librustc_typeck/check/compare_method.rs | 10 +-- src/librustc_typeck/check/intrinsic.rs | 4 +- src/librustc_typeck/check/method/confirm.rs | 2 +- src/librustc_typeck/check/method/mod.rs | 3 +- src/librustc_typeck/check/method/probe.rs | 6 +- src/librustc_typeck/check/mod.rs | 26 +++---- src/librustc_typeck/check/wfcheck.rs | 10 +-- src/librustc_typeck/collect.rs | 17 +++-- src/librustc_typeck/impl_wf_check.rs | 4 +- src/librustdoc/clean/auto_trait.rs | 40 +++++------ src/librustdoc/clean/mod.rs | 19 +++-- 27 files changed, 186 insertions(+), 126 deletions(-) diff --git a/src/librustc/hir/lowering.rs b/src/librustc/hir/lowering.rs index 51f0c1d7047c..e05c686f39fc 100644 --- a/src/librustc/hir/lowering.rs +++ b/src/librustc/hir/lowering.rs @@ -1461,7 +1461,7 @@ impl<'a> LoweringContext<'a> { assert!(!def_id.is_local()); let n = self.cstore .item_generics_cloned_untracked(def_id, self.sess) - .regions + .lifetimes() .len(); self.type_def_lifetime_params.insert(def_id, n); n diff --git a/src/librustc/ich/impls_ty.rs b/src/librustc/ich/impls_ty.rs index 1036eae9b856..c7f0979766cf 100644 --- a/src/librustc/ich/impls_ty.rs +++ b/src/librustc/ich/impls_ty.rs @@ -735,10 +735,8 @@ impl<'a> HashStable> for ty::Generics { hasher: &mut StableHasher) { let ty::Generics { parent, - parent_regions, - parent_types, - ref regions, - ref types, + ref parent_parameters, + ref parameters, // Reverse map to each `TypeParameterDef`'s `index` field, from // `def_id.index` (`def_id.krate` is the same as the item's). @@ -748,15 +746,18 @@ impl<'a> HashStable> for ty::Generics { } = *self; parent.hash_stable(hcx, hasher); - parent_regions.hash_stable(hcx, hasher); - parent_types.hash_stable(hcx, hasher); - regions.hash_stable(hcx, hasher); - types.hash_stable(hcx, hasher); + parent_parameters.hash_stable(hcx, hasher); + parameters.hash_stable(hcx, hasher); has_self.hash_stable(hcx, hasher); has_late_bound_regions.hash_stable(hcx, hasher); } } +impl_stable_hash_for!(enum ty::GenericParameterDef { + Lifetime(lt), + Type(ty) +}); + impl<'a> HashStable> for ty::RegionParameterDef { fn hash_stable(&self, diff --git a/src/librustc/infer/anon_types/mod.rs b/src/librustc/infer/anon_types/mod.rs index 725ea9734abf..9cf55e85693a 100644 --- a/src/librustc/infer/anon_types/mod.rs +++ b/src/librustc/infer/anon_types/mod.rs @@ -313,7 +313,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { // `['a]` for the first impl trait and `'b` for the // second. let mut least_region = None; - for region_def in &abstract_type_generics.regions { + for region_def in abstract_type_generics.lifetimes() { // Find the index of this region in the list of substitutions. let index = region_def.index as usize; diff --git a/src/librustc/middle/resolve_lifetime.rs b/src/librustc/middle/resolve_lifetime.rs index 8c19a1952327..8f44507035af 100644 --- a/src/librustc/middle/resolve_lifetime.rs +++ b/src/librustc/middle/resolve_lifetime.rs @@ -1659,7 +1659,7 @@ impl<'a, 'tcx> LifetimeContext<'a, 'tcx> { .entry(def_id) .or_insert_with(|| { tcx.generics_of(def_id) - .types + .types() .iter() .map(|def| def.object_lifetime_default) .collect() diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 25be4a2ff5c8..dfe0cd6900e7 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -378,7 +378,7 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { flags.push(("_Self".to_string(), Some(self.tcx.type_of(def.did).to_string()))); } - for param in generics.types.iter() { + for param in generics.types().iter() { let name = param.name.to_string(); let ty = trait_ref.substs.type_for_def(param); let ty_str = ty.to_string(); diff --git a/src/librustc/traits/object_safety.rs b/src/librustc/traits/object_safety.rs index c0d5a337cee3..10228c5783c5 100644 --- a/src/librustc/traits/object_safety.rs +++ b/src/librustc/traits/object_safety.rs @@ -284,7 +284,7 @@ impl<'a, 'gcx, 'tcx> TyCtxt<'a, 'gcx, 'tcx> { } // We can't monomorphize things like `fn foo(...)`. - if !self.generics_of(method.def_id).types.is_empty() { + if !self.generics_of(method.def_id).types().is_empty() { return Some(MethodViolationCode::Generic); } diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index 3cf7af30b3d5..b2fc2c171063 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -243,7 +243,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { let name = tcx.item_name(trait_def_id); let generics = tcx.generics_of(trait_def_id); let parser = Parser::new(&self.0); - let types = &generics.types; + let types = generics.types(); let mut result = Ok(()); for token in parser { match token { @@ -288,7 +288,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { let name = tcx.item_name(trait_ref.def_id); let trait_str = tcx.item_path_str(trait_ref.def_id); let generics = tcx.generics_of(trait_ref.def_id); - let generic_map = generics.types.iter().map(|param| { + let generic_map = generics.types().iter().map(|param| { (param.name.to_string(), trait_ref.substs.type_for_def(param).to_string()) }).collect::>(); diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index eede7bd2ea61..f32316ac5472 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -757,6 +757,21 @@ impl ty::EarlyBoundRegion { } } +#[derive(Clone, Debug, RustcEncodable, RustcDecodable)] +pub enum GenericParameterDef { + Lifetime(RegionParameterDef), + Type(TypeParameterDef), +} + +impl GenericParameterDef { + pub fn index(&self) -> u32 { + match self { + GenericParameterDef::Lifetime(lt) => lt.index, + GenericParameterDef::Type(ty) => ty.index, + } + } +} + /// Information about the formal type/lifetime parameters associated /// with an item or method. Analogous to hir::Generics. /// @@ -769,10 +784,8 @@ impl ty::EarlyBoundRegion { #[derive(Clone, Debug, RustcEncodable, RustcDecodable)] pub struct Generics { pub parent: Option, - pub parent_regions: u32, - pub parent_types: u32, - pub regions: Vec, - pub types: Vec, + pub parent_parameters: Vec, + pub parameters: Vec, /// Reverse map to each `TypeParameterDef`'s `index` field pub type_param_to_index: FxHashMap, @@ -783,24 +796,56 @@ pub struct Generics { impl<'a, 'gcx, 'tcx> Generics { pub fn parent_count(&self) -> usize { - self.parent_regions as usize + self.parent_types as usize + self.parent_parameters.iter().map(|&x| x as usize).sum() } pub fn own_count(&self) -> usize { - self.regions.len() + self.types.len() + self.parameters.len() } pub fn count(&self) -> usize { self.parent_count() + self.own_count() } + pub fn lifetimes(&self) -> Vec<&RegionParameterDef> { + self.parameters.iter().filter_map(|p| { + if let GenericParameterDef::Lifetime(lt) = p { + Some(lt) + } else { + None + } + }).collect() + } + + pub fn types(&self) -> Vec<&TypeParameterDef> { + self.parameters.iter().filter_map(|p| { + if let GenericParameterDef::Type(ty) = p { + Some(ty) + } else { + None + } + }).collect() + } + + pub fn parent_lifetimes(&self) -> u32 { + self.parent_parameters[0] + } + + pub fn parent_types(&self) -> u32 { + self.parent_parameters[1] + } + pub fn region_param(&'tcx self, param: &EarlyBoundRegion, tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx RegionParameterDef { if let Some(index) = param.index.checked_sub(self.parent_count() as u32) { - &self.regions[index as usize - self.has_self as usize] + // 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, + _ => bug!("expected region parameter, but found another generic parameter") + } } else { tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) .region_param(param, tcx) @@ -840,17 +885,23 @@ impl<'a, 'gcx, 'tcx> Generics { // And it can be seen that in both cases, to move from a substs // offset to a generics offset you just have to offset by the // number of regions. - let type_param_offset = self.regions.len(); + let type_param_offset = self.lifetimes().len(); let has_self = self.has_self && self.parent.is_none(); let is_separated_self = type_param_offset != 0 && idx == 0 && has_self; - if let Some(idx) = (idx as usize).checked_sub(type_param_offset) { + if let Some(_) = (idx as usize).checked_sub(type_param_offset) { assert!(!is_separated_self, "found a Self after type_param_offset"); - &self.types[idx] + match self.parameters[idx as usize] { + ty::GenericParameterDef::Type(ref ty) => ty, + _ => bug!("expected type parameter, but found another generic parameter") + } } else { assert!(is_separated_self, "non-Self param before type_param_offset"); - &self.types[0] + match self.parameters[type_param_offset] { + ty::GenericParameterDef::Type(ref ty) => ty, + _ => bug!("expected type parameter, but found another generic parameter") + } } } else { tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) diff --git a/src/librustc/ty/subst.rs b/src/librustc/ty/subst.rs index e7b58ae1564a..fa2aa9720064 100644 --- a/src/librustc/ty/subst.rs +++ b/src/librustc/ty/subst.rs @@ -242,24 +242,31 @@ impl<'a, 'gcx, 'tcx> Substs<'tcx> { where FR: FnMut(&ty::RegionParameterDef, &[Kind<'tcx>]) -> ty::Region<'tcx>, FT: FnMut(&ty::TypeParameterDef, &[Kind<'tcx>]) -> Ty<'tcx> { // Handle Self first, before all regions. - let mut types = defs.types.iter(); - if defs.parent.is_none() && defs.has_self { + let types = defs.types(); + let mut types = types.iter(); + let mut skip_self = defs.parent.is_none() && defs.has_self; + if skip_self { let def = types.next().unwrap(); let ty = mk_type(def, substs); assert_eq!(def.index as usize, substs.len()); substs.push(ty.into()); } - for def in &defs.regions { - let region = mk_region(def, substs); - assert_eq!(def.index as usize, substs.len()); - substs.push(Kind::from(region)); - } - - for def in types { - let ty = mk_type(def, substs); - assert_eq!(def.index as usize, substs.len()); - substs.push(Kind::from(ty)); + for def in &defs.parameters { + let param = match def { + ty::GenericParameterDef::Lifetime(ref lt) => { + UnpackedKind::Lifetime(mk_region(lt, substs)) + } + ty::GenericParameterDef::Type(ref ty) => { + if skip_self { + skip_self = false; + continue + } + UnpackedKind::Type(mk_type(ty, substs)) + } + }; + assert_eq!(def.index() as usize, substs.len()); + substs.push(param.pack()); } } diff --git a/src/librustc/util/ppaux.rs b/src/librustc/util/ppaux.rs index a6eb468e3383..5b287e416297 100644 --- a/src/librustc/util/ppaux.rs +++ b/src/librustc/util/ppaux.rs @@ -310,10 +310,10 @@ impl PrintContext { if let Some(def_id) = generics.parent { // Methods. assert!(is_value_path); - child_types = generics.types.len(); + child_types = generics.types().len(); generics = tcx.generics_of(def_id); - num_regions = generics.regions.len(); - num_types = generics.types.len(); + num_regions = generics.lifetimes().len(); + num_types = generics.types().len(); if has_self { print!(f, self, write("<"), print_display(substs.type_at(0)), write(" as "))?; @@ -328,16 +328,16 @@ impl PrintContext { assert_eq!(has_self, false); } else { // Types and traits. - num_regions = generics.regions.len(); - num_types = generics.types.len(); + num_regions = generics.lifetimes().len(); + num_types = generics.types().len(); } } if !verbose { - if generics.types.last().map_or(false, |def| def.has_default) { + if generics.types().last().map_or(false, |def| def.has_default) { if let Some(substs) = tcx.lift(&substs) { let tps = substs.types().rev().skip(child_types); - for (def, actual) in generics.types.iter().rev().zip(tps) { + for (def, actual) in generics.types().iter().rev().zip(tps) { if !def.has_default { break; } diff --git a/src/librustc_metadata/encoder.rs b/src/librustc_metadata/encoder.rs index d7a06f7932fe..7e580e9333ff 100644 --- a/src/librustc_metadata/encoder.rs +++ b/src/librustc_metadata/encoder.rs @@ -929,7 +929,7 @@ impl<'a, 'b: 'a, 'tcx: 'b> IsolatedEncoder<'a, 'b, '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 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(); diff --git a/src/librustc_mir/monomorphize/collector.rs b/src/librustc_mir/monomorphize/collector.rs index e690e8ee8806..bfdf81588afd 100644 --- a/src/librustc_mir/monomorphize/collector.rs +++ b/src/librustc_mir/monomorphize/collector.rs @@ -1076,7 +1076,7 @@ impl<'b, 'a, 'v> RootCollector<'b, 'a, 'v> { 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.parent_types() as usize + generics.types().len() > 0 } fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, @@ -1108,7 +1108,7 @@ fn create_mono_items_for_default_impls<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, continue; } - if !tcx.generics_of(method.def_id).types.is_empty() { + if !tcx.generics_of(method.def_id).types().is_empty() { continue; } diff --git a/src/librustc_mir/transform/check_unsafety.rs b/src/librustc_mir/transform/check_unsafety.rs index 2bf5a49c97e8..1e8707157f75 100644 --- a/src/librustc_mir/transform/check_unsafety.rs +++ b/src/librustc_mir/transform/check_unsafety.rs @@ -357,7 +357,7 @@ fn unsafe_derive_on_repr_packed<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, def_id: D // FIXME: when we make this a hard error, this should have its // own error code. - let message = if !tcx.generics_of(def_id).types.is_empty() { + let message = if !tcx.generics_of(def_id).types().is_empty() { format!("#[derive] can't be used on a #[repr(packed)] struct with \ type parameters (error E0133)") } else { diff --git a/src/librustc_privacy/lib.rs b/src/librustc_privacy/lib.rs index 42031d9cc563..445717ac6008 100644 --- a/src/librustc_privacy/lib.rs +++ b/src/librustc_privacy/lib.rs @@ -399,7 +399,7 @@ impl<'a, 'tcx> Visitor<'tcx> for EmbargoVisitor<'a, 'tcx> { impl<'b, 'a, 'tcx> ReachEverythingInTheInterfaceVisitor<'b, 'a, 'tcx> { fn generics(&mut self) -> &mut Self { - for def in &self.ev.tcx.generics_of(self.item_def_id).types { + for def in &self.ev.tcx.generics_of(self.item_def_id).types() { if def.has_default { self.ev.tcx.type_of(def.def_id).visit_with(self); } @@ -1335,7 +1335,7 @@ struct SearchInterfaceForPrivateItemsVisitor<'a, 'tcx: 'a> { impl<'a, 'tcx: 'a> SearchInterfaceForPrivateItemsVisitor<'a, 'tcx> { fn generics(&mut self) -> &mut Self { - for def in &self.tcx.generics_of(self.item_def_id).types { + for def in &self.tcx.generics_of(self.item_def_id).types() { if def.has_default { self.tcx.type_of(def.def_id).visit_with(self); } diff --git a/src/librustc_trans/debuginfo/mod.rs b/src/librustc_trans/debuginfo/mod.rs index 30676b91620a..be9aa49c100a 100644 --- a/src/librustc_trans/debuginfo/mod.rs +++ b/src/librustc_trans/debuginfo/mod.rs @@ -417,7 +417,7 @@ pub fn create_function_debug_context<'a, 'tcx>(cx: &CodegenCx<'a, 'tcx>, let mut names = generics.parent.map_or(vec![], |def_id| { get_type_parameter_names(cx, cx.tcx.generics_of(def_id)) }); - names.extend(generics.types.iter().map(|param| param.name)); + names.extend(generics.types().iter().map(|param| param.name)); names } diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index d307ef30044e..4286946599a7 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -209,7 +209,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { // whatever & would get replaced with). let decl_generics = tcx.generics_of(def_id); let num_types_provided = parameters.types.len(); - let expected_num_region_params = decl_generics.regions.len(); + let expected_num_region_params = decl_generics.lifetimes().len(); let supplied_num_region_params = parameters.lifetimes.len(); if expected_num_region_params != supplied_num_region_params { report_lifetime_number_error(tcx, span, @@ -221,7 +221,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { assert_eq!(decl_generics.has_self, self_ty.is_some()); // Check the number of type parameters supplied by the user. - let ty_param_defs = &decl_generics.types[self_ty.is_some() as usize..]; + let ty_param_defs = &decl_generics.types()[self_ty.is_some() as usize..]; if !infer_types || num_types_provided > ty_param_defs.len() { check_type_argument_count(tcx, span, num_types_provided, ty_param_defs); } @@ -254,7 +254,7 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { return ty; } - let i = i - self_ty.is_some() as usize - decl_generics.regions.len(); + let i = i - self_ty.is_some() as usize - decl_generics.lifetimes().len(); if i < num_types_provided { // A provided type parameter. self.ast_ty_to_ty(¶meters.types[i]) @@ -1300,7 +1300,7 @@ fn split_auto_traits<'a, 'b, 'gcx, 'tcx>(tcx: TyCtxt<'a, 'gcx, 'tcx>, } fn check_type_argument_count(tcx: TyCtxt, span: Span, supplied: usize, - ty_param_defs: &[ty::TypeParameterDef]) { + ty_param_defs: &[&ty::TypeParameterDef]) { let accepted = ty_param_defs.len(); let required = ty_param_defs.iter().take_while(|x| !x.has_default).count(); if supplied < required { diff --git a/src/librustc_typeck/check/compare_method.rs b/src/librustc_typeck/check/compare_method.rs index 91264849cadf..1dce514023a5 100644 --- a/src/librustc_typeck/check/compare_method.rs +++ b/src/librustc_typeck/check/compare_method.rs @@ -357,8 +357,8 @@ fn check_region_bounds_on_impl_method<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, trait_to_skol_substs: &Substs<'tcx>) -> Result<(), ErrorReported> { let span = tcx.sess.codemap().def_span(span); - let trait_params = &trait_generics.regions[..]; - let impl_params = &impl_generics.regions[..]; + let trait_params = trait_generics.lifetimes(); + let impl_params = impl_generics.lifetimes(); debug!("check_region_bounds_on_impl_method: \ trait_generics={:?} \ @@ -574,8 +574,8 @@ fn compare_number_of_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, -> Result<(), ErrorReported> { let impl_m_generics = tcx.generics_of(impl_m.def_id); let trait_m_generics = tcx.generics_of(trait_m.def_id); - let num_impl_m_type_params = impl_m_generics.types.len(); - let num_trait_m_type_params = trait_m_generics.types.len(); + let num_impl_m_type_params = impl_m_generics.types().len(); + let num_trait_m_type_params = trait_m_generics.types().len(); if num_impl_m_type_params != num_trait_m_type_params { let impl_m_node_id = tcx.hir.as_local_node_id(impl_m.def_id).unwrap(); let impl_m_item = tcx.hir.expect_impl_item(impl_m_node_id); @@ -728,7 +728,7 @@ fn compare_synthetic_generics<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, let mut error_found = false; let impl_m_generics = tcx.generics_of(impl_m.def_id); let trait_m_generics = tcx.generics_of(trait_m.def_id); - for (impl_ty, trait_ty) in impl_m_generics.types.iter().zip(trait_m_generics.types.iter()) { + for (impl_ty, trait_ty) in impl_m_generics.types().iter().zip(trait_m_generics.types().iter()) { if impl_ty.synthetic != trait_ty.synthetic { let impl_node_id = tcx.hir.as_local_node_id(impl_ty.def_id).unwrap(); let impl_span = tcx.hir.span(impl_node_id); diff --git a/src/librustc_typeck/check/intrinsic.rs b/src/librustc_typeck/check/intrinsic.rs index fcf7541a159b..50a3cab6d2bb 100644 --- a/src/librustc_typeck/check/intrinsic.rs +++ b/src/librustc_typeck/check/intrinsic.rs @@ -45,7 +45,7 @@ fn equate_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, } } - let i_n_tps = tcx.generics_of(def_id).types.len(); + let i_n_tps = tcx.generics_of(def_id).types().len(); if i_n_tps != n_tps { let span = match it.node { hir::ForeignItemFn(_, _, ref generics) => generics.span, @@ -346,7 +346,7 @@ pub fn check_platform_intrinsic_type<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, }; let def_id = tcx.hir.local_def_id(it.id); - let i_n_tps = tcx.generics_of(def_id).types.len(); + let i_n_tps = tcx.generics_of(def_id).types().len(); let name = it.name.as_str(); let (n_tps, inputs, output) = match &*name { diff --git a/src/librustc_typeck/check/method/confirm.rs b/src/librustc_typeck/check/method/confirm.rs index 46288181037f..3accb51f3087 100644 --- a/src/librustc_typeck/check/method/confirm.rs +++ b/src/librustc_typeck/check/method/confirm.rs @@ -332,7 +332,7 @@ impl<'a, 'gcx, 'tcx> ConfirmContext<'a, 'gcx, 'tcx> { parent_substs.type_at(i) } else if let Some(ast_ty) = provided.as_ref().and_then(|p| { - p.types.get(i - parent_substs.len() - method_generics.regions.len()) + p.types.get(i - parent_substs.len() - method_generics.lifetimes().len()) }) { self.to_ty(ast_ty) diff --git a/src/librustc_typeck/check/method/mod.rs b/src/librustc_typeck/check/method/mod.rs index 5f904a9419b1..8d7d8cb0f5f6 100644 --- a/src/librustc_typeck/check/method/mod.rs +++ b/src/librustc_typeck/check/method/mod.rs @@ -288,8 +288,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let method_item = self.associated_item(trait_def_id, m_name, Namespace::Value).unwrap(); let def_id = method_item.def_id; let generics = tcx.generics_of(def_id); - assert_eq!(generics.types.len(), 0); - assert_eq!(generics.regions.len(), 0); + assert_eq!(generics.parameters.len(), 0); debug!("lookup_in_trait_adjusted: method_item={:?}", method_item); let mut obligations = vec![]; diff --git a/src/librustc_typeck/check/method/probe.rs b/src/librustc_typeck/check/method/probe.rs index e45565c2f522..d3335fdd9807 100644 --- a/src/librustc_typeck/check/method/probe.rs +++ b/src/librustc_typeck/check/method/probe.rs @@ -1378,14 +1378,14 @@ impl<'a, 'gcx, 'tcx> ProbeContext<'a, 'gcx, 'tcx> { // method yet. So create fresh variables here for those too, // if there are any. let generics = self.tcx.generics_of(method); - assert_eq!(substs.types().count(), generics.parent_types as usize); - assert_eq!(substs.regions().count(), generics.parent_regions as usize); + assert_eq!(substs.regions().count(), generics.parent_lifetimes() as usize); + assert_eq!(substs.types().count(), generics.parent_types() as usize); // Erase any late-bound regions from the method and substitute // in the values from the substitution. let xform_fn_sig = self.erase_late_bound_regions(&fn_sig); - if generics.types.is_empty() && generics.regions.is_empty() { + if generics.parameters.is_empty() { xform_fn_sig.subst(self.tcx, substs) } else { let substs = Substs::for_item(self.tcx, method, |def, _| { diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index b4a7de7b8443..1faf1f7e8828 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -1239,7 +1239,7 @@ pub fn check_item_type<'a,'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, it: &'tcx hir::Item } else { for item in &m.items { let generics = tcx.generics_of(tcx.hir.local_def_id(item.id)); - if !generics.types.is_empty() { + if !generics.types().is_empty() { let mut err = struct_span_err!(tcx.sess, item.span, E0044, "foreign items may not have type parameters"); err.span_label(item.span, "can't have type parameters"); @@ -4799,7 +4799,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Skip over the lifetimes in the same segment. if let Some((_, generics)) = segment { - i -= generics.regions.len(); + i -= generics.lifetimes().len(); } if let Some(ast_ty) = types.get(i) { @@ -4918,11 +4918,11 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { }; // Check provided type parameters. - let type_defs = segment.map_or(&[][..], |(_, generics)| { + let type_defs = segment.map_or(vec![], |(_, generics)| { if generics.parent.is_none() { - &generics.types[generics.has_self as usize..] + generics.types()[generics.has_self as usize..].to_vec() } else { - &generics.types + generics.types() } }); let required_len = type_defs.iter().take_while(|d| !d.has_default).count(); @@ -4957,7 +4957,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } // Check provided lifetime parameters. - let lifetime_defs = segment.map_or(&[][..], |(_, generics)| &generics.regions); + let lifetime_defs = segment.map_or(vec![], |(_, generics)| generics.lifetimes()); let required_len = lifetime_defs.len(); // Prohibit explicit lifetime arguments if late bound lifetime parameters are present. @@ -5014,13 +5014,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let segment = segment.map(|(path_segment, generics)| { let explicit = !path_segment.infer_types; - let impl_trait = generics.types.iter() - .any(|ty_param| { - match ty_param.synthetic { - Some(ImplTrait) => true, - _ => false, - } - }); + let impl_trait = generics.types().iter() + .any(|ty_param| { + match ty_param.synthetic { + Some(ImplTrait) => true, + _ => false, + } + }); if explicit && impl_trait { let mut err = struct_span_err! { diff --git a/src/librustc_typeck/check/wfcheck.rs b/src/librustc_typeck/check/wfcheck.rs index d0ff44c8e7e1..ec1f654d44b1 100644 --- a/src/librustc_typeck/check/wfcheck.rs +++ b/src/librustc_typeck/check/wfcheck.rs @@ -641,12 +641,12 @@ fn report_bivariance<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, fn reject_shadowing_type_parameters(tcx: TyCtxt, def_id: DefId) { let generics = tcx.generics_of(def_id); let parent = tcx.generics_of(generics.parent.unwrap()); - let impl_params: FxHashMap<_, _> = parent.types - .iter() - .map(|tp| (tp.name, tp.def_id)) - .collect(); + let impl_params: FxHashMap<_, _> = parent.types() + .iter() + .map(|tp| (tp.name, tp.def_id)) + .collect(); - for method_param in &generics.types { + for method_param in generics.types() { if impl_params.contains_key(&method_param.name) { // Tighten up the span to focus on only the shadowing type let type_span = tcx.def_span(method_param.def_id); diff --git a/src/librustc_typeck/collect.rs b/src/librustc_typeck/collect.rs index f0f392a2458e..bb3086688691 100644 --- a/src/librustc_typeck/collect.rs +++ b/src/librustc_typeck/collect.rs @@ -881,8 +881,8 @@ fn generics_of<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, assert_eq!(has_self, false); parent_has_self = generics.has_self; own_start = generics.count() as u32; - (generics.parent_regions + generics.regions.len() as u32, - generics.parent_types + generics.types.len() as u32) + (generics.parent_lifetimes() + generics.lifetimes().len() as u32, + generics.parent_types() + generics.types().len() as u32) }); let early_lifetimes = early_bound_lifetimes_from_generics(tcx, ast_generics); @@ -971,12 +971,17 @@ 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 = + types.into_iter().map(|ty| ty::GenericParameterDef::Type(ty)).collect(); + let parameters = lifetimes.into_iter().chain(types.into_iter()).collect(); + tcx.alloc_generics(ty::Generics { parent: parent_def_id, - parent_regions, - parent_types, - regions, - types, + parent_parameters, + parameters, type_param_to_index, has_self: has_self || parent_has_self, has_late_bound_regions: has_late_bound_regions(tcx, node), diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index faf3ccb1133a..fe51e182044c 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -105,7 +105,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, tcx, &impl_predicates.predicates.as_slice(), impl_trait_ref, &mut input_parameters); // Disallow ANY unconstrained type parameters. - for (ty_param, param) in impl_generics.types.iter().zip(impl_hir_generics.ty_params()) { + for (ty_param, param) in impl_generics.types().iter().zip(impl_hir_generics.ty_params()) { let param_ty = ty::ParamTy::for_def(ty_param); if !input_parameters.contains(&ctp::Parameter::from(param_ty)) { report_unused_parameter(tcx, param.span, "type", ¶m_ty.to_string()); @@ -122,7 +122,7 @@ fn enforce_impl_params_are_constrained<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>, .flat_map(|def_id| { ctp::parameters_for(&tcx.type_of(def_id), true) }).collect(); - for (ty_lifetime, lifetime) in impl_generics.regions.iter() + for (ty_lifetime, lifetime) in impl_generics.lifetimes().iter() .zip(impl_hir_generics.lifetimes()) { let param = ctp::Parameter::from(ty_lifetime.to_early_bound_region_data()); diff --git a/src/librustdoc/clean/auto_trait.rs b/src/librustdoc/clean/auto_trait.rs index 722dcb7fe6a7..7601bac67b06 100644 --- a/src/librustdoc/clean/auto_trait.rs +++ b/src/librustdoc/clean/auto_trait.rs @@ -225,30 +225,28 @@ impl<'a, 'tcx, 'rcx> AutoTraitFinder<'a, 'tcx, 'rcx> { fn generics_to_path_params(&self, generics: ty::Generics) -> hir::PathParameters { let lifetimes = HirVec::from_vec( - generics - .regions - .iter() - .map(|p| { - let name = if p.name == "" { - hir::LifetimeName::Static - } else { - hir::LifetimeName::Name(p.name.as_symbol()) - }; + generics.lifetimes() + .iter() + .map(|p| { + let name = if p.name == "" { + hir::LifetimeName::Static + } else { + hir::LifetimeName::Name(p.name.as_symbol()) + }; - hir::Lifetime { - id: ast::DUMMY_NODE_ID, - span: DUMMY_SP, - name, - } - }) - .collect(), + hir::Lifetime { + id: ast::DUMMY_NODE_ID, + span: DUMMY_SP, + name, + } + }) + .collect(), ); let types = HirVec::from_vec( - generics - .types - .iter() - .map(|p| P(self.ty_param_to_ty(p.clone()))) - .collect(), + generics.types() + .into_iter() + .map(|p| P(self.ty_param_to_ty(p.clone()))) + .collect(), ); hir::PathParameters { diff --git a/src/librustdoc/clean/mod.rs b/src/librustdoc/clean/mod.rs index 7d3ba7928293..eec92184ac49 100644 --- a/src/librustdoc/clean/mod.rs +++ b/src/librustdoc/clean/mod.rs @@ -1800,7 +1800,7 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, // Bounds in the type_params and lifetimes fields are repeated in the // predicates field (see rustc_typeck::collect::ty_generics), so remove // them. - let stripped_typarams = gens.types.iter().filter_map(|tp| { + let stripped_typarams = gens.types().iter().filter_map(|tp| { if tp.name == keywords::SelfType.name().as_str() { assert_eq!(tp.index, 0); None @@ -1849,16 +1849,15 @@ impl<'a, 'tcx> Clean for (&'a ty::Generics, // and instead see `where T: Foo + Bar + Sized + 'a` Generics { - params: gens.regions - .clean(cx) - .into_iter() - .map(|lp| GenericParam::Lifetime(lp)) - .chain( - simplify::ty_params(stripped_typarams) + params: gens.lifetimes() .into_iter() - .map(|tp| GenericParam::Type(tp)) - ) - .collect(), + .map(|lp| GenericParam::Lifetime(lp.clean(cx))) + .chain( + simplify::ty_params(stripped_typarams) + .into_iter() + .map(|tp| GenericParam::Type(tp)) + ) + .collect(), where_predicates: simplify::where_clauses(cx, where_predicates), } }