Rollup merge of #103827 - compiler-errors:rpitit-substs-compat, r=wesleywiser
Properly remap and check for substs compatibility in `confirm_impl_trait_in_trait_candidate` Fixes #103824
This commit is contained in:
commit
6c021cf07d
@ -430,7 +430,9 @@ pub fn note_and_explain_type_err(
|
||||
(ty::Projection(_), ty::Projection(_)) => {
|
||||
diag.note("an associated type was expected, but a different one was found");
|
||||
}
|
||||
(ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p)) => {
|
||||
(ty::Param(p), ty::Projection(proj)) | (ty::Projection(proj), ty::Param(p))
|
||||
if self.def_kind(proj.item_def_id) != DefKind::ImplTraitPlaceholder =>
|
||||
{
|
||||
let generics = self.generics_of(body_owner_def_id);
|
||||
let p_span = self.def_span(generics.type_param(p, self).def_id);
|
||||
if !sp.contains(p_span) {
|
||||
|
@ -2187,7 +2187,7 @@ 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,
|
||||
assoc_item: &ty::AssocItem,
|
||||
substs: ty::SubstsRef<'tcx>,
|
||||
) -> bool {
|
||||
fn check_substs_compatible_inner<'tcx>(
|
||||
@ -2219,7 +2219,10 @@ fn check_substs_compatible_inner<'tcx>(
|
||||
true
|
||||
}
|
||||
|
||||
check_substs_compatible_inner(tcx, tcx.generics_of(assoc_ty.def_id), substs.as_slice())
|
||||
let generics = tcx.generics_of(assoc_item.def_id);
|
||||
// Chop off any additional substs (RPITIT) substs
|
||||
let substs = &substs[0..generics.count().min(substs.len())];
|
||||
check_substs_compatible_inner(tcx, generics, substs)
|
||||
}
|
||||
|
||||
fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
@ -2248,11 +2251,27 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
|
||||
};
|
||||
}
|
||||
|
||||
let impl_fn_def_id = leaf_def.item.def_id;
|
||||
// Rebase from {trait}::{fn}::{opaque} to {impl}::{fn}::{opaque},
|
||||
// since `data.substs` are the impl substs.
|
||||
let impl_fn_substs =
|
||||
obligation.predicate.substs.rebase_onto(tcx, tcx.parent(trait_fn_def_id), data.substs);
|
||||
let impl_fn_substs = translate_substs(
|
||||
selcx.infcx(),
|
||||
obligation.param_env,
|
||||
data.impl_def_id,
|
||||
impl_fn_substs,
|
||||
leaf_def.defining_node,
|
||||
);
|
||||
|
||||
if !check_substs_compatible(tcx, &leaf_def.item, impl_fn_substs) {
|
||||
let err = tcx.ty_error_with_message(
|
||||
obligation.cause.span,
|
||||
"impl method and trait method have different parameters",
|
||||
);
|
||||
return Progress { term: err.into(), obligations };
|
||||
}
|
||||
|
||||
let impl_fn_def_id = leaf_def.item.def_id;
|
||||
|
||||
let cause = ObligationCause::new(
|
||||
obligation.cause.span,
|
||||
|
17
src/test/ui/impl-trait/in-trait/generics-mismatch.rs
Normal file
17
src/test/ui/impl-trait/in-trait/generics-mismatch.rs
Normal file
@ -0,0 +1,17 @@
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
struct U;
|
||||
|
||||
trait Foo {
|
||||
fn bar(&self) -> impl Sized;
|
||||
}
|
||||
|
||||
impl Foo for U {
|
||||
fn bar<T>(&self) {}
|
||||
//~^ ERROR method `bar` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
}
|
||||
|
||||
fn main() {
|
||||
U.bar();
|
||||
}
|
12
src/test/ui/impl-trait/in-trait/generics-mismatch.stderr
Normal file
12
src/test/ui/impl-trait/in-trait/generics-mismatch.stderr
Normal file
@ -0,0 +1,12 @@
|
||||
error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
|
||||
--> $DIR/generics-mismatch.rs:11:12
|
||||
|
|
||||
LL | fn bar(&self) -> impl Sized;
|
||||
| - expected 0 type parameters
|
||||
...
|
||||
LL | fn bar<T>(&self) {}
|
||||
| ^ found 1 type parameter
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0049`.
|
26
src/test/ui/impl-trait/in-trait/specialization-broken.rs
Normal file
26
src/test/ui/impl-trait/in-trait/specialization-broken.rs
Normal file
@ -0,0 +1,26 @@
|
||||
// FIXME(compiler-errors): I'm not exactly sure if this is expected to pass or not.
|
||||
// But we fixed an ICE anyways.
|
||||
|
||||
#![feature(specialization)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Foo {
|
||||
fn bar(&self) -> impl Sized;
|
||||
}
|
||||
|
||||
default impl<U> Foo for U
|
||||
where
|
||||
U: Copy,
|
||||
{
|
||||
fn bar(&self) -> U {
|
||||
//~^ ERROR method `bar` has an incompatible type for trait
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl Foo for i32 {}
|
||||
|
||||
fn main() {
|
||||
1i32.bar();
|
||||
}
|
23
src/test/ui/impl-trait/in-trait/specialization-broken.stderr
Normal file
23
src/test/ui/impl-trait/in-trait/specialization-broken.stderr
Normal file
@ -0,0 +1,23 @@
|
||||
error[E0053]: method `bar` has an incompatible type for trait
|
||||
--> $DIR/specialization-broken.rs:16:22
|
||||
|
|
||||
LL | default impl<U> Foo for U
|
||||
| - this type parameter
|
||||
...
|
||||
LL | fn bar(&self) -> U {
|
||||
| ^
|
||||
| |
|
||||
| expected associated type, found type parameter `U`
|
||||
| help: change the output type to match the trait: `impl Sized`
|
||||
|
|
||||
note: type in trait
|
||||
--> $DIR/specialization-broken.rs:9:22
|
||||
|
|
||||
LL | fn bar(&self) -> impl Sized;
|
||||
| ^^^^^^^^^^
|
||||
= note: expected fn pointer `fn(&U) -> impl Sized`
|
||||
found fn pointer `fn(&U) -> U`
|
||||
|
||||
error: aborting due to previous error
|
||||
|
||||
For more information about this error, try `rustc --explain E0053`.
|
@ -0,0 +1,24 @@
|
||||
// check-pass
|
||||
|
||||
#![feature(specialization)]
|
||||
#![feature(return_position_impl_trait_in_trait)]
|
||||
#![allow(incomplete_features)]
|
||||
|
||||
trait Foo {
|
||||
fn bar(&self) -> impl Sized;
|
||||
}
|
||||
|
||||
impl<U> Foo for U
|
||||
where
|
||||
U: Copy,
|
||||
{
|
||||
fn bar(&self) -> U {
|
||||
*self
|
||||
}
|
||||
}
|
||||
|
||||
impl Foo for i32 {}
|
||||
|
||||
fn main() {
|
||||
let _: i32 = 1i32.bar();
|
||||
}
|
Loading…
Reference in New Issue
Block a user