Skip to content

Commit a2037e3

Browse files
Check for substs compatibility for RPITITs
1 parent 95a3a72 commit a2037e3

File tree

3 files changed

+44
-3
lines changed

3 files changed

+44
-3
lines changed

compiler/rustc_trait_selection/src/traits/project.rs

+15-3
Original file line numberDiff line numberDiff line change
@@ -2192,7 +2192,7 @@ fn confirm_impl_candidate<'cx, 'tcx>(
21922192
// Verify that the trait item and its implementation have compatible substs lists
21932193
fn check_substs_compatible<'tcx>(
21942194
tcx: TyCtxt<'tcx>,
2195-
assoc_ty: &ty::AssocItem,
2195+
assoc_item: &ty::AssocItem,
21962196
substs: ty::SubstsRef<'tcx>,
21972197
) -> bool {
21982198
fn check_substs_compatible_inner<'tcx>(
@@ -2224,7 +2224,10 @@ fn check_substs_compatible<'tcx>(
22242224
true
22252225
}
22262226

2227-
check_substs_compatible_inner(tcx, tcx.generics_of(assoc_ty.def_id), substs.as_slice())
2227+
let generics = tcx.generics_of(assoc_item.def_id);
2228+
// Chop off any additional substs (RPITIT) substs
2229+
let substs = &substs[0..generics.count().min(substs.len())];
2230+
check_substs_compatible_inner(tcx, generics, substs)
22282231
}
22292232

22302233
fn confirm_impl_trait_in_trait_candidate<'tcx>(
@@ -2253,12 +2256,21 @@ fn confirm_impl_trait_in_trait_candidate<'tcx>(
22532256
};
22542257
}
22552258

2256-
let impl_fn_def_id = leaf_def.item.def_id;
22572259
// Rebase from {trait}::{fn}::{opaque} to {impl}::{fn}::{opaque},
22582260
// since `data.substs` are the impl substs.
22592261
let impl_fn_substs =
22602262
obligation.predicate.substs.rebase_onto(tcx, tcx.parent(trait_fn_def_id), data.substs);
22612263

2264+
if !check_substs_compatible(tcx, &leaf_def.item, impl_fn_substs) {
2265+
let err = tcx.ty_error_with_message(
2266+
obligation.cause.span,
2267+
"impl method and trait method have different parameters",
2268+
);
2269+
return Progress { term: err.into(), obligations };
2270+
}
2271+
2272+
let impl_fn_def_id = leaf_def.item.def_id;
2273+
22622274
let cause = ObligationCause::new(
22632275
obligation.cause.span,
22642276
obligation.cause.body_id,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#![feature(return_position_impl_trait_in_trait)]
2+
#![allow(incomplete_features)]
3+
4+
struct U;
5+
6+
trait Foo {
7+
fn bar(&self) -> impl Sized;
8+
}
9+
10+
impl Foo for U {
11+
fn bar<T>(&self) {}
12+
//~^ ERROR method `bar` has 1 type parameter but its trait declaration has 0 type parameters
13+
}
14+
15+
fn main() {
16+
U.bar();
17+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
2+
--> $DIR/generics-mismatch.rs:11:12
3+
|
4+
LL | fn bar(&self) -> impl Sized;
5+
| - expected 0 type parameters
6+
...
7+
LL | fn bar<T>(&self) {}
8+
| ^ found 1 type parameter
9+
10+
error: aborting due to previous error
11+
12+
For more information about this error, try `rustc --explain E0049`.

0 commit comments

Comments
 (0)