exit out of compare_number_of_generics early

This commit is contained in:
Ellen 2022-05-05 12:41:43 +01:00
parent 6225e980bf
commit 4208c53ed6
5 changed files with 48 additions and 31 deletions

View File

@ -579,6 +579,27 @@ fn compare_self_type<'tcx>(
Ok(()) Ok(())
} }
/// Checks that the number of generics on a given assoc item in a trait impl is the same
/// as the number of generics on the respective assoc item in the trait definition.
///
/// For example this code emits the errors in the following code:
/// ```
/// trait Trait {
/// fn foo();
/// type Assoc<T>;
/// }
///
/// impl Trait for () {
/// fn foo<T>() {}
/// //~^ error
/// type Assoc = u32;
/// //~^ error
/// }
/// ```
///
/// Notably this does not error on `foo<T>` implemented as `foo<const N: u8>` or
/// `foo<const N: u8>` implemented as `foo<const N: u32>`. This is handled in
/// [`compare_generic_param_kinds`]. This function also does not handle lifetime parameters
fn compare_number_of_generics<'tcx>( fn compare_number_of_generics<'tcx>(
tcx: TyCtxt<'tcx>, tcx: TyCtxt<'tcx>,
impl_: &ty::AssocItem, impl_: &ty::AssocItem,
@ -589,6 +610,15 @@ fn compare_number_of_generics<'tcx>(
let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts(); let trait_own_counts = tcx.generics_of(trait_.def_id).own_counts();
let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts(); let impl_own_counts = tcx.generics_of(impl_.def_id).own_counts();
// This avoids us erroring on `foo<T>` implemented as `foo<const N: u8>` as this is implemented
// in `compare_generic_param_kinds` which will give a nicer error message than something like:
// "expected 1 type parameter, found 0 type parameters"
if (trait_own_counts.types + trait_own_counts.consts)
== (impl_own_counts.types + impl_own_counts.consts)
{
return Ok(());
}
let matchings = [ let matchings = [
("type", trait_own_counts.types, impl_own_counts.types), ("type", trait_own_counts.types, impl_own_counts.types),
("const", trait_own_counts.consts, impl_own_counts.consts), ("const", trait_own_counts.consts, impl_own_counts.consts),

View File

@ -3,7 +3,7 @@ trait Trait {
} }
impl Trait for () { impl Trait for () {
fn foo<const M: u64>() {} fn foo<const M: u64>() {}
//~^ error: method `foo` has an incompatble generic parameter for trait //~^ error: method `foo` has an incompatible generic parameter for trait
} }
trait Other { trait Other {
@ -19,7 +19,7 @@ trait Uwu {
} }
impl Uwu for () { impl Uwu for () {
fn baz<const N: i32>() {} fn baz<const N: i32>() {}
//~^ error: method `baz` has an incompatible generic parameter for trait //~^ error: method `baz` has an incompatible const parameter type for trait
} }
fn main() {} fn main() {}

View File

@ -1,38 +1,26 @@
error[E0049]: method `foo` has 0 type parameters but its trait declaration has 1 type parameter error[E0053]: method `foo` has an incompatible generic parameter for trait
--> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12 --> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12
| |
LL | fn foo<U>() {}
| - expected 1 type parameter
...
LL | fn foo<const M: u64>() {} LL | fn foo<const M: u64>() {}
| ^^^^^^^^^^^^ found 0 type parameters | ^^^^^^^^^^^^
|
error[E0049]: method `foo` has 1 const parameter but its trait declaration has 0 const parameters 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
--> $DIR/mismatched_ty_const_in_trait_impl.rs:5:12 --> $DIR/mismatched_ty_const_in_trait_impl.rs:2:12
| |
LL | fn foo<U>() {} LL | fn foo<U>() {}
| - expected 0 const parameters | ^
...
LL | fn foo<const M: u64>() {}
| ^^^^^^^^^^^^ found 1 const parameter
error[E0049]: method `bar` has 1 type parameter but its trait declaration has 0 type parameters error[E0053]: method `bar` has an incompatible generic parameter for trait
--> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12 --> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12
| |
LL | fn bar<const M: u8>() {}
| ----------- expected 0 type parameters
...
LL | fn bar<T>() {} LL | fn bar<T>() {}
| ^ found 1 type parameter | ^
|
error[E0049]: method `bar` has 0 const parameters but its trait declaration has 1 const parameter 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`
--> $DIR/mismatched_ty_const_in_trait_impl.rs:13:12 --> $DIR/mismatched_ty_const_in_trait_impl.rs:10:12
| |
LL | fn bar<const M: u8>() {} LL | fn bar<const M: u8>() {}
| ----------- expected 1 const parameter | ^^^^^^^^^^^
...
LL | fn bar<T>() {}
| ^ found 0 const parameters
error[E0053]: method `baz` has an incompatible const parameter type for trait error[E0053]: method `baz` has an incompatible const parameter type for trait
--> $DIR/mismatched_ty_const_in_trait_impl.rs:21:12 --> $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:
LL | fn baz<const N: u32>() {} LL | fn baz<const N: u32>() {}
| ^^^^^^^^^^^^ | ^^^^^^^^^^^^
error: aborting due to 5 previous errors error: aborting due to 3 previous errors
Some errors have detailed explanations: E0049, E0053. For more information about this error, try `rustc --explain E0053`.
For more information about an error, try `rustc --explain E0049`.

View File

@ -6,7 +6,7 @@ trait Trait {
impl Trait for () { impl Trait for () {
type Foo<const N: u64> = u32; type Foo<const N: u64> = u32;
//~^ error: associated type `Foo` has an incompatible const parameter type //~^ error: type `Foo` has an incompatible const parameter type
} }
fn main() {} fn main() {}

View File

@ -1,4 +1,4 @@
error[E0053]: associated type `Foo` has an incompatible const parameter type for trait error[E0053]: type `Foo` has an incompatible const parameter type for trait
--> $DIR/const_params_have_right_type.rs:8:14 --> $DIR/const_params_have_right_type.rs:8:14
| |
LL | type Foo<const N: u64> = u32; LL | type Foo<const N: u64> = u32;