Skip to content

Commit 4208c53

Browse files
committed
exit out of compare_number_of_generics early
1 parent 6225e98 commit 4208c53

File tree

5 files changed

+48
-31
lines changed

5 files changed

+48
-31
lines changed

compiler/rustc_typeck/src/check/compare_method.rs

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -579,6 +579,27 @@ fn compare_self_type<'tcx>(
579579
Ok(())
580580
}
581581

582+
/// Checks that the number of generics on a given assoc item in a trait impl is the same
583+
/// as the number of generics on the respective assoc item in the trait definition.
584+
///
585+
/// For example this code emits the errors in the following code:
586+
/// ```
587+
/// trait Trait {
588+
/// fn foo();
589+
/// type Assoc<T>;
590+
/// }
591+
///
592+
/// impl Trait for () {
593+
/// fn foo<T>() {}
594+
/// //~^ error
595+
/// type Assoc = u32;
596+
/// //~^ error
597+
/// }
598+
/// ```
599+
///
600+
/// Notably this does not error on `foo<T>` implemented as `foo<const N: u8>` or
601+
/// `foo<const N: u8>` implemented as `foo<const N: u32>`. This is handled in
602+
/// [`compare_generic_param_kinds`]. This function also does not handle lifetime parameters
582603
fn compare_number_of_generics<'tcx>(
583604
tcx: TyCtxt<'tcx>,
584605
impl_: &ty::AssocItem,
@@ -589,6 +610,15 @@ fn compare_number_of_generics<'tcx>(
589610
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
590611
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
591612

613+
// This avoids us erroring on `foo<T>` implemented as `foo<const N: u8>` as this is implemented
614+
// in `compare_generic_param_kinds` which will give a nicer error message than something like:
615+
// "expected 1 type parameter, found 0 type parameters"
616+
if (trait_own_counts.types + trait_own_counts.consts)
617+
== (impl_own_counts.types + impl_own_counts.consts)
618+
{
619+
return Ok(());
620+
}
621+
592622
let matchings = [
593623
("type", trait_own_counts.types, impl_own_counts.types),
594624
("const", trait_own_counts.consts, impl_own_counts.consts),

src/test/ui/const-generics/defaults/mismatched_ty_const_in_trait_impl.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@ trait Trait {
33
}
44
impl Trait for () {
55
fn foo<const M: u64>() {}
6-
//~^ error: method `foo` has an incompatble generic parameter for trait
6+
//~^ error: method `foo` has an incompatible generic parameter for trait
77
}
88

99
trait Other {
@@ -19,7 +19,7 @@ trait Uwu {
1919
}
2020
impl Uwu for () {
2121
fn baz<const N: i32>() {}
22-
//~^ error: method `baz` has an incompatible generic parameter for trait
22+
//~^ error: method `baz` has an incompatible const parameter type for trait
2323
}
2424

2525
fn main() {}
Lines changed: 14 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,26 @@
1-
error[E0049]: method `foo` has 0 type parameters but its trait declaration has 1 type parameter
1+
error[E0053]: method `foo` has an incompatible generic parameter for trait
22
--> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12
33
|
4-
LL | fn foo<U>() {}
5-
| - expected 1 type parameter
6-
...
74
LL | fn foo<const M: u64>() {}
8-
| ^^^^^^^^^^^^ found 0 type parameters
9-
10-
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters
11-
--> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12
5+
| ^^^^^^^^^^^^
6+
|
7+
note: the trait impl specifies `M` is a const parameter of type `u64`, but the declaration in trait `Trait::foo` requires it is a type parameter
8+
--> $DIR/mismatched_ty_const_in_trait_impl.rs:2:12
129
|
1310
LL | fn foo<U>() {}
14-
| - expected 0 const parameters
15-
...
16-
LL | fn foo<const M: u64>() {}
17-
| ^^^^^^^^^^^^ found 1 const parameter
11+
| ^
1812

19-
error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters
13+
error[E0053]: method `bar` has an incompatible generic parameter for trait
2014
--> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12
2115
|
22-
LL | fn bar<const M: u8>() {}
23-
| ----------- expected 0 type parameters
24-
...
2516
LL | fn bar<T>() {}
26-
| ^ found 1 type parameter
27-
28-
error[E0049]: method `bar` has 0 const parameters but its trait declaration has 1 const parameter
29-
--> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12
17+
| ^
18+
|
19+
note: the trait impl specifies `T` is a type parameter, but the declaration in trait `Other::bar` requires it is a const parameter of type `u8`
20+
--> $DIR/mismatched_ty_const_in_trait_impl.rs:10:12
3021
|
3122
LL | fn bar<const M: u8>() {}
32-
| ----------- expected 1 const parameter
33-
...
34-
LL | fn bar<T>() {}
35-
| ^ found 0 const parameters
23+
| ^^^^^^^^^^^
3624

3725
error[E0053]: method `baz` has an incompatible const parameter type for trait
3826
--> $DIR/mismatched_ty_const_in_trait_impl.rs:21:12
@@ -46,7 +34,6 @@ note: the const parameter `N` has type `i32`, but the declaration in trait `Uwu:
4634
LL | fn baz<const N: u32>() {}
4735
| ^^^^^^^^^^^^
4836

49-
error: aborting due to 5 previous errors
37+
error: aborting due to 3 previous errors
5038

51-
Some errors have detailed explanations: E0049, E0053.
52-
For more information about an error, try `rustc --explain E0049`.
39+
For more information about this error, try `rustc --explain E0053`.

src/test/ui/generic-associated-types/const_params_have_right_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ trait Trait {
66

77
impl Trait for () {
88
type Foo<const N: u64> = u32;
9-
//~^ error: associated type `Foo` has an incompatible const parameter type
9+
//~^ error: type `Foo` has an incompatible const parameter type
1010
}
1111

1212
fn main() {}

src/test/ui/generic-associated-types/const_params_have_right_type.stderr

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
error[E0053]: associated type `Foo` has an incompatible const parameter type for trait
1+
error[E0053]: type `Foo` has an incompatible const parameter type for trait
22
--> $DIR/const_params_have_right_type.rs:8:14
33
|
44
LL | type Foo<const N: u64> = u32;

0 commit comments

Comments
 (0)