mirror of
https://github.com/rust-lang/rust.git
synced 2025-06-04 19:29:07 +00:00
Clean up generic param handling
This commit is contained in:
parent
25bf73d31c
commit
030f10f752
@ -382,13 +382,12 @@ impl<'a, 'gcx, 'tcx> InferCtxt<'a, 'gcx, 'tcx> {
|
|||||||
for param in generics.params.iter() {
|
for param in generics.params.iter() {
|
||||||
let value = match param.kind {
|
let value = match param.kind {
|
||||||
GenericParamDefKind::Type(_) => {
|
GenericParamDefKind::Type(_) => {
|
||||||
let ty = trait_ref.substs.type_for_def(¶m);
|
trait_ref.substs[param.index as usize].to_string()
|
||||||
ty.to_string()
|
|
||||||
},
|
},
|
||||||
GenericParamDefKind::Lifetime => continue,
|
GenericParamDefKind::Lifetime => continue,
|
||||||
};
|
};
|
||||||
let name = param.name.to_string();
|
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()) {
|
if let Some(true) = self_ty.ty_to_def_id().map(|def_id| def_id.is_local()) {
|
||||||
|
@ -290,7 +290,7 @@ impl<'a, 'gcx, 'tcx> OnUnimplementedFormatString {
|
|||||||
let generic_map = generics.params.iter().filter_map(|param| {
|
let generic_map = generics.params.iter().filter_map(|param| {
|
||||||
let value = match param.kind {
|
let value = match param.kind {
|
||||||
GenericParamDefKind::Type(_) => {
|
GenericParamDefKind::Type(_) => {
|
||||||
trait_ref.substs.type_for_def(¶m).to_string()
|
trait_ref.substs[param.index as usize].to_string()
|
||||||
},
|
},
|
||||||
GenericParamDefKind::Lifetime => return None
|
GenericParamDefKind::Lifetime => return None
|
||||||
};
|
};
|
||||||
|
@ -837,7 +837,7 @@ impl<'a, 'gcx, 'tcx> Generics {
|
|||||||
let param = &self.params[index as usize];
|
let param = &self.params[index as usize];
|
||||||
match param.kind {
|
match param.kind {
|
||||||
ty::GenericParamDefKind::Lifetime => param,
|
ty::GenericParamDefKind::Lifetime => param,
|
||||||
_ => bug!("expected region parameter, but found another generic parameter")
|
_ => bug!("expected lifetime parameter, but found another generic parameter")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
|
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: TyCtxt<'a, 'gcx, 'tcx>)
|
||||||
-> &'tcx GenericParamDef {
|
-> &'tcx GenericParamDef {
|
||||||
if let Some(index) = param.idx.checked_sub(self.parent_count as u32) {
|
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 {
|
} else {
|
||||||
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
|
tcx.generics_of(self.parent.expect("parent_count>0 but no parent?"))
|
||||||
.type_param(param, tcx)
|
.type_param(param, tcx)
|
||||||
|
@ -87,6 +87,11 @@ struct ConvertedBinding<'tcx> {
|
|||||||
span: Span,
|
span: Span,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct ParamRange {
|
||||||
|
required: usize,
|
||||||
|
accepted: usize
|
||||||
|
}
|
||||||
|
|
||||||
/// Dummy type used for the `Self` of a `TraitRef` created for converting
|
/// Dummy type used for the `Self` of a `TraitRef` created for converting
|
||||||
/// a trait object, and which gets removed in `ExistentialTraitRef`.
|
/// a trait object, and which gets removed in `ExistentialTraitRef`.
|
||||||
/// This type must not appear anywhere in other converted types.
|
/// 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 lt_provided = parameters.lifetimes.len();
|
||||||
|
|
||||||
let mut lt_accepted = 0;
|
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 {
|
for param in &decl_generics.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {
|
GenericParamDefKind::Lifetime => {
|
||||||
lt_accepted += 1;
|
lt_accepted += 1;
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Type(ty) => {
|
GenericParamDefKind::Type(ty) => {
|
||||||
ty_range.1 += 1;
|
ty_params.accepted += 1;
|
||||||
if !ty.has_default {
|
if !ty.has_default {
|
||||||
ty_range.0 += 1;
|
ty_params.required += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if self_ty.is_some() {
|
if self_ty.is_some() {
|
||||||
ty_range.0 -= 1;
|
ty_params.required -= 1;
|
||||||
ty_range.1 -= 1;
|
ty_params.accepted -= 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if lt_accepted != lt_provided {
|
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());
|
assert_eq!(decl_generics.has_self, self_ty.is_some());
|
||||||
|
|
||||||
// Check the number of type parameters supplied by the user.
|
// Check the number of type parameters supplied by the user.
|
||||||
if !infer_types || ty_provided > ty_range.0 {
|
if !infer_types || ty_provided > ty_params.required {
|
||||||
check_type_argument_count(tcx, span, ty_provided, ty_range);
|
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);
|
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,
|
fn check_type_argument_count(tcx: TyCtxt,
|
||||||
span: Span,
|
span: Span,
|
||||||
supplied: usize,
|
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 {
|
if supplied < required {
|
||||||
let expected = if required < accepted {
|
let expected = if required < accepted {
|
||||||
"expected at least"
|
"expected at least"
|
||||||
|
@ -4925,27 +4925,32 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
|
|||||||
// Check provided parameters.
|
// Check provided parameters.
|
||||||
let ((ty_required, ty_accepted), lt_accepted) =
|
let ((ty_required, ty_accepted), lt_accepted) =
|
||||||
segment.map_or(((0, 0), 0), |(_, generics)| {
|
segment.map_or(((0, 0), 0), |(_, generics)| {
|
||||||
|
struct ParamRange {
|
||||||
|
required: usize,
|
||||||
|
accepted: usize
|
||||||
|
};
|
||||||
|
|
||||||
let mut lt_accepted = 0;
|
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 {
|
for param in &generics.params {
|
||||||
match param.kind {
|
match param.kind {
|
||||||
GenericParamDefKind::Lifetime => {
|
GenericParamDefKind::Lifetime => {
|
||||||
lt_accepted += 1;
|
lt_accepted += 1;
|
||||||
}
|
}
|
||||||
GenericParamDefKind::Type(ty) => {
|
GenericParamDefKind::Type(ty) => {
|
||||||
ty_range.1 += 1;
|
ty_params.accepted += 1;
|
||||||
if !ty.has_default {
|
if !ty.has_default {
|
||||||
ty_range.0 += 1;
|
ty_params.required += 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
if generics.parent.is_none() && generics.has_self {
|
if generics.parent.is_none() && generics.has_self {
|
||||||
ty_range.0 -= 1;
|
ty_params.required -= 1;
|
||||||
ty_range.1 -= 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 {
|
if types.len() > ty_accepted {
|
||||||
|
@ -72,7 +72,7 @@ struct ImplWfCheck<'a, 'tcx: 'a> {
|
|||||||
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> {
|
impl<'a, 'tcx> ItemLikeVisitor<'tcx> for ImplWfCheck<'a, 'tcx> {
|
||||||
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
fn visit_item(&mut self, item: &'tcx hir::Item) {
|
||||||
match item.node {
|
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);
|
let impl_def_id = self.tcx.hir.local_def_id(item.id);
|
||||||
enforce_impl_params_are_constrained(self.tcx,
|
enforce_impl_params_are_constrained(self.tcx,
|
||||||
impl_def_id,
|
impl_def_id,
|
||||||
|
Loading…
Reference in New Issue
Block a user