From 030f10f752b6584e4f1974c104dd644dfffd80ad Mon Sep 17 00:00:00 2001 From: varkor Date: Mon, 14 May 2018 12:49:32 +0100 Subject: [PATCH] Clean up generic param handling --- src/librustc/traits/error_reporting.rs | 5 ++--- src/librustc/traits/on_unimplemented.rs | 2 +- src/librustc/ty/mod.rs | 8 ++++++-- src/librustc_typeck/astconv.rs | 23 ++++++++++++++--------- src/librustc_typeck/check/mod.rs | 17 +++++++++++------ src/librustc_typeck/impl_wf_check.rs | 2 +- 6 files changed, 35 insertions(+), 22 deletions(-) diff --git a/src/librustc/traits/error_reporting.rs b/src/librustc/traits/error_reporting.rs index 18c0020a2b4..934069974be 100644 --- a/src/librustc/traits/error_reporting.rs +++ b/src/librustc/traits/error_reporting.rs @@ -382,13 +382,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> { for param in generics.params.iter() { let value = match param.kind { GenericParamDefKind::Type(_) => { - let ty = trait_ref.substs.type_for_def(¶m); - ty.to_string() + trait_ref.substs[param.index as usize].to_string() }, GenericParamDefKind::Lifetime => continue, }; let name = param.name.to_string(); - flags.push((name.clone(), Some(value.clone()))); + flags.push((name, Some(value))); } if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) { diff --git a/src/librustc/traits/on_unimplemented.rs b/src/librustc/traits/on_unimplemented.rs index bc558c2933c..539f40cf3ef 100644 --- a/src/librustc/traits/on_unimplemented.rs +++ b/src/librustc/traits/on_unimplemented.rs @@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString { let generic_map = generics.params.iter().filter_map(|param| { let value = match param.kind { GenericParamDefKind::Type(_) => { - trait_ref.substs.type_for_def(¶m).to_string() + trait_ref.substs[param.index as usize].to_string() }, GenericParamDefKind::Lifetime => return None }; diff --git a/src/librustc/ty/mod.rs b/src/librustc/ty/mod.rs index 4818006b9e7..6861683ed12 100644 --- a/src/librustc/ty/mod.rs +++ b/src/librustc/ty/mod.rs @@ -837,7 +837,7 @@ impl<'a, 'gcx, 'tcx> Generics { let param = &self.params[index as usize]; match param.kind { ty::GenericParamDefKind::Lifetime => param, - _ => bug!("expected region parameter, but found another generic parameter") + _ => bug!("expected lifetime parameter, but found another generic parameter") } } else { tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) @@ -851,7 +851,11 @@ impl<'a, 'gcx, 'tcx> Generics { tcx: TyCtxt<'a, 'gcx, 'tcx>) -> &'tcx GenericParamDef { if let Some(index) = param.idx.checked_sub(self.parent_count as u32) { - &self.params[index as usize] + let param = &self.params[index as usize]; + match param.kind { + ty::GenericParamDefKind::Type(_) => param, + _ => bug!("expected type parameter, but found another generic parameter") + } } else { tcx.generics_of(self.parent.expect("parent_count>0 but no parent?")) .type_param(param, tcx) diff --git a/src/librustc_typeck/astconv.rs b/src/librustc_typeck/astconv.rs index ec685dd8c4c..12e1bfde224 100644 --- a/src/librustc_typeck/astconv.rs +++ b/src/librustc_typeck/astconv.rs @@ -87,6 +87,11 @@ struct ConvertedBinding<'tcx> { span: Span, } +struct ParamRange { + required: usize, + accepted: usize +} + /// Dummy type used for the `Self` of a `TraitRef` created for converting /// a trait object, and which gets removed in `ExistentialTraitRef`. /// This type must not appear anywhere in other converted types. @@ -212,23 +217,23 @@ impl<'o, 'gcx: 'tcx, 'tcx> AstConv<'gcx, 'tcx>+'o { let lt_provided = parameters.lifetimes.len(); let mut lt_accepted = 0; - let mut ty_range = (0, 0); + let mut ty_params = ParamRange { required: 0, accepted: 0 }; for param in &decl_generics.params { match param.kind { GenericParamDefKind::Lifetime => { lt_accepted += 1; } GenericParamDefKind::Type(ty) => { - ty_range.1 += 1; + ty_params.accepted += 1; if !ty.has_default { - ty_range.0 += 1; + ty_params.required += 1; } } }; } if self_ty.is_some() { - ty_range.0 -= 1; - ty_range.1 -= 1; + ty_params.required -= 1; + ty_params.accepted -= 1; } if lt_accepted != lt_provided { @@ -239,8 +244,8 @@ 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. - if !infer_types || ty_provided > ty_range.0 { - check_type_argument_count(tcx, span, ty_provided, ty_range); + if !infer_types || ty_provided > ty_params.required { + check_type_argument_count(tcx, span, ty_provided, ty_params); } let is_object = self_ty.map_or(false, |ty| ty.sty == TRAIT_OBJECT_DUMMY_SELF); @@ -1327,9 +1332,9 @@ 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_range: (usize, usize)) + ty_params: ParamRange) { - let (required, accepted) = ty_range; + let (required, accepted) = (ty_params.required, ty_params.accepted); if supplied < required { let expected = if required < accepted { "expected at least" diff --git a/src/librustc_typeck/check/mod.rs b/src/librustc_typeck/check/mod.rs index 70d29c60a10..7e33bf9722f 100644 --- a/src/librustc_typeck/check/mod.rs +++ b/src/librustc_typeck/check/mod.rs @@ -4925,27 +4925,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { // Check provided parameters. let ((ty_required, ty_accepted), lt_accepted) = segment.map_or(((0, 0), 0), |(_, generics)| { + struct ParamRange { + required: usize, + accepted: usize + }; + let mut lt_accepted = 0; - let mut ty_range = (0, 0); + let mut ty_params = ParamRange { required: 0, accepted: 0 }; for param in &generics.params { match param.kind { GenericParamDefKind::Lifetime => { lt_accepted += 1; } GenericParamDefKind::Type(ty) => { - ty_range.1 += 1; + ty_params.accepted += 1; if !ty.has_default { - ty_range.0 += 1; + ty_params.required += 1; } } }; } if generics.parent.is_none() && generics.has_self { - ty_range.0 -= 1; - ty_range.1 -= 1; + ty_params.required -= 1; + ty_params.accepted -= 1; } - ((ty_range.0, ty_range.1), lt_accepted) + ((ty_params.required, ty_params.accepted), lt_accepted) }); if types.len() > ty_accepted { diff --git a/src/librustc_typeck/impl_wf_check.rs b/src/librustc_typeck/impl_wf_check.rs index 1ba967ce4b0..80dde814c66 100644 --- a/src/librustc_typeck/impl_wf_check.rs +++ b/src/librustc_typeck/impl_wf_check.rs @@ -72,7 +72,7 @@ struct ImplWfCheck<'a, 'tcx: 'a> { impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> { fn visit_item(&mut self, item: &'tcx hir::Item) { match item.node { - hir::ItemImpl(.., _, _, _, ref impl_item_refs) => { + hir::ItemImpl(.., ref impl_item_refs) => { let impl_def_id = self.tcx.hir.local_def_id(item.id); enforce_impl_params_are_constrained(self.tcx, impl_def_id,