Skip to content

Commit 94e047b

Browse files
Check generics parity between impl and trait before collecting RPITITs
1 parent 28a53cd commit 94e047b

File tree

3 files changed

+50
-3
lines changed

3 files changed

+50
-3
lines changed

compiler/rustc_hir_analysis/src/check/compare_method.rs

+11-3
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ pub(crate) fn compare_impl_method<'tcx>(
5151
return;
5252
}
5353

54-
if let Err(_) = compare_number_of_generics(tcx, impl_m, impl_m_span, trait_m, trait_item_span) {
54+
if let Err(_) = compare_number_of_generics(tcx, impl_m, trait_m, trait_item_span) {
5555
return;
5656
}
5757

@@ -352,6 +352,10 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
352352
let impl_trait_ref = tcx.impl_trait_ref(impl_m.impl_container(tcx).unwrap()).unwrap();
353353
let param_env = tcx.param_env(def_id);
354354

355+
// First, check a few of the same thing as `compare_impl_method`, just so we don't ICE during substitutions later.
356+
compare_number_of_generics(tcx, impl_m, trait_m, tcx.hir().span_if_local(impl_m.def_id))?;
357+
compare_generic_param_kinds(tcx, impl_m, trait_m)?;
358+
355359
let trait_to_impl_substs = impl_trait_ref.substs;
356360

357361
let impl_m_hir_id = tcx.hir().local_def_id_to_hir_id(impl_m.def_id.expect_local());
@@ -376,6 +380,7 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
376380
let infcx = &tcx.infer_ctxt().build();
377381
let ocx = ObligationCtxt::new(infcx);
378382

383+
// Normalize the impl signature with fresh variables for lifetime inference.
379384
let norm_cause = ObligationCause::misc(return_span, impl_m_hir_id);
380385
let impl_sig = ocx.normalize(
381386
norm_cause.clone(),
@@ -388,6 +393,10 @@ pub fn collect_trait_impl_trait_tys<'tcx>(
388393
);
389394
let impl_return_ty = impl_sig.output();
390395

396+
// Normalize the trait signature with liberated bound vars, passing it through
397+
// the ImplTraitInTraitCollector, which gathers all of the RPITITs and replaces
398+
// them with inference variables.
399+
// We will use these inference variables to collect the hidden types of RPITITs.
391400
let mut collector = ImplTraitInTraitCollector::new(&ocx, return_span, param_env, impl_m_hir_id);
392401
let unnormalized_trait_sig = tcx
393402
.liberate_late_bound_regions(
@@ -922,7 +931,6 @@ fn compare_self_type<'tcx>(
922931
fn compare_number_of_generics<'tcx>(
923932
tcx: TyCtxt<'tcx>,
924933
impl_: &ty::AssocItem,
925-
_impl_span: Span,
926934
trait_: &ty::AssocItem,
927935
trait_span: Option<Span>,
928936
) -> Result<(), ErrorGuaranteed> {
@@ -1489,7 +1497,7 @@ pub(crate) fn compare_ty_impl<'tcx>(
14891497
debug!("compare_impl_type(impl_trait_ref={:?})", impl_trait_ref);
14901498

14911499
let _: Result<(), ErrorGuaranteed> = (|| {
1492-
compare_number_of_generics(tcx, impl_ty, impl_ty_span, trait_ty, trait_item_span)?;
1500+
compare_number_of_generics(tcx, impl_ty, trait_ty, trait_item_span)?;
14931501

14941502
compare_generic_param_kinds(tcx, impl_ty, trait_ty)?;
14951503

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#![feature(return_position_impl_trait_in_trait)]
2+
#![allow(incomplete_features)]
3+
4+
struct S;
5+
6+
trait Foo {
7+
fn bar<T>() -> impl Sized;
8+
}
9+
10+
impl Foo for S {
11+
fn bar() -> impl Sized {}
12+
//~^ ERROR method `bar` has 0 type parameters but its trait declaration has 1 type parameter
13+
//~| ERROR method `bar` has 0 type parameters but its trait declaration has 1 type parameter
14+
}
15+
16+
fn main() {
17+
S::bar();
18+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
2+
--> $DIR/trait-more-generics-than-impl.rs:11:11
3+
|
4+
LL | fn bar<T>() -> impl Sized;
5+
| - expected 1 type parameter
6+
...
7+
LL | fn bar() -> impl Sized {}
8+
| ^ found 0 type parameters
9+
10+
error[E0049]: method `bar` has 0 type parameters but its trait declaration has 1 type parameter
11+
--> $DIR/trait-more-generics-than-impl.rs:11:11
12+
|
13+
LL | fn bar<T>() -> impl Sized;
14+
| - expected 1 type parameter
15+
...
16+
LL | fn bar() -> impl Sized {}
17+
| ^ found 0 type parameters
18+
19+
error: aborting due to 2 previous errors
20+
21+
For more information about this error, try `rustc --explain E0049`.

0 commit comments

Comments
 (0)