Check generic argument compatibility when projecting assoc ty
This commit is contained in:
parent
594134d873
commit
ee713f3d43
3 changed files with 68 additions and 2 deletions
|
@ -2146,10 +2146,10 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
||||||
} else {
|
} else {
|
||||||
ty.map_bound(|ty| ty.into())
|
ty.map_bound(|ty| ty.into())
|
||||||
};
|
};
|
||||||
if substs.len() != tcx.generics_of(assoc_ty.item.def_id).count() {
|
if !check_substs_compatible(tcx, &assoc_ty.item, substs) {
|
||||||
let err = tcx.ty_error_with_message(
|
let err = tcx.ty_error_with_message(
|
||||||
obligation.cause.span,
|
obligation.cause.span,
|
||||||
"impl item and trait item have different parameter counts",
|
"impl item and trait item have different parameters",
|
||||||
);
|
);
|
||||||
Progress { term: err.into(), obligations: nested }
|
Progress { term: err.into(), obligations: nested }
|
||||||
} else {
|
} else {
|
||||||
|
@ -2158,6 +2158,44 @@ fn confirm_impl_candidate<'cx, 'tcx>(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Verify that the trait item and its implementation have compatible substs lists
|
||||||
|
fn check_substs_compatible<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
assoc_ty: &ty::AssocItem,
|
||||||
|
substs: ty::SubstsRef<'tcx>,
|
||||||
|
) -> bool {
|
||||||
|
fn check_substs_compatible_inner<'tcx>(
|
||||||
|
tcx: TyCtxt<'tcx>,
|
||||||
|
generics: &'tcx ty::Generics,
|
||||||
|
args: &'tcx [ty::GenericArg<'tcx>],
|
||||||
|
) -> bool {
|
||||||
|
if generics.count() != args.len() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
let (parent_args, own_args) = args.split_at(generics.parent_count);
|
||||||
|
|
||||||
|
if let Some(parent) = generics.parent
|
||||||
|
&& let parent_generics = tcx.generics_of(parent)
|
||||||
|
&& !check_substs_compatible_inner(tcx, parent_generics, parent_args) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (param, arg) in std::iter::zip(&generics.params, own_args) {
|
||||||
|
match (¶m.kind, arg.unpack()) {
|
||||||
|
(ty::GenericParamDefKind::Type { .. }, ty::GenericArgKind::Type(_))
|
||||||
|
| (ty::GenericParamDefKind::Lifetime, ty::GenericArgKind::Lifetime(_))
|
||||||
|
| (ty::GenericParamDefKind::Const { .. }, ty::GenericArgKind::Const(_)) => {}
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
check_substs_compatible_inner(tcx, tcx.generics_of(assoc_ty.def_id), substs.as_slice())
|
||||||
|
}
|
||||||
|
|
||||||
fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||||
selcx: &mut SelectionContext<'_, 'tcx>,
|
selcx: &mut SelectionContext<'_, 'tcx>,
|
||||||
obligation: &ProjectionTyObligation<'tcx>,
|
obligation: &ProjectionTyObligation<'tcx>,
|
||||||
|
|
16
src/test/ui/generic-associated-types/issue-102114.rs
Normal file
16
src/test/ui/generic-associated-types/issue-102114.rs
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
trait A {
|
||||||
|
type B<'b>;
|
||||||
|
fn a() -> Self::B<'static>;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct C;
|
||||||
|
|
||||||
|
struct Wrapper<T>(T);
|
||||||
|
|
||||||
|
impl A for C {
|
||||||
|
type B<T> = Wrapper<T>;
|
||||||
|
//~^ ERROR type `B` has 1 type parameter but its trait declaration has 0 type parameters
|
||||||
|
fn a() -> Self::B<'static> {}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {}
|
12
src/test/ui/generic-associated-types/issue-102114.stderr
Normal file
12
src/test/ui/generic-associated-types/issue-102114.stderr
Normal file
|
@ -0,0 +1,12 @@
|
||||||
|
error[E0049]: type `B` has 1 type parameter but its trait declaration has 0 type parameters
|
||||||
|
--> $DIR/issue-102114.rs:11:12
|
||||||
|
|
|
||||||
|
LL | type B<'b>;
|
||||||
|
| -- expected 0 type parameters
|
||||||
|
...
|
||||||
|
LL | type B<T> = Wrapper<T>;
|
||||||
|
| ^ found 1 type parameter
|
||||||
|
|
||||||
|
error: aborting due to previous error
|
||||||
|
|
||||||
|
For more information about this error, try `rustc --explain E0049`.
|
Loading…
Add table
Add a link
Reference in a new issue