Rollup merge of #86843 - FabianWolff:issue-86820, r=lcnr

Check that const parameters of trait methods have compatible types

This PR fixes #86820. The problem is that this currently passes the type checker:
```rust
trait Tr {
    fn foo<const N: u8>(self) -> u8;
}

impl Tr for f32 {
    fn foo<const N: bool>(self) -> u8 { 42 }
}
```
i.e. the type checker fails to check whether const parameters in `impl` methods have the same type as the corresponding declaration in the trait. With my changes, I get, for the above code:
```
error[E0053]: method `foo` has an incompatible const parameter type for trait
 --> test.rs:6:18
  |
6 |     fn foo<const N: bool>(self) -> u8 { 42 }
  |                  ^
  |
note: the const parameter `N` has type `bool`, but the declaration in trait `Tr::foo` has type `u8`
 --> test.rs:2:18
  |
2 |     fn foo<const N: u8>(self) -> u8;
  |                  ^

error: aborting due to previous error
```
This fixes #86820, where an ICE happens later on because the trait method is declared with a const parameter of type `u8`, but the `impl` uses one of type `usize`:
> `expected int of size 8, but got size 1`
This commit is contained in:
Yuki Okushi 2021-07-18 14:21:54 +09:00 committed by GitHub
commit 783efd29ae
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 106 additions and 0 deletions

View file

@ -0,0 +1,25 @@
// Regression test for the ICE described in #86820.
#![allow(unused,dead_code)]
use std::ops::BitAnd;
const C: fn() = || is_set();
fn is_set() {
0xffu8.bit::<0>();
}
trait Bits {
fn bit<const I : u8>(self) -> bool;
//~^ NOTE: the const parameter `I` has type `usize`, but the declaration in trait `Bits::bit` has type `u8`
}
impl Bits for u8 {
fn bit<const I : usize>(self) -> bool {
//~^ ERROR: method `bit` has an incompatible const parameter type for trait [E0053]
let i = 1 << I;
let mask = u8::from(i);
mask & self == mask
}
}
fn main() {}

View file

@ -0,0 +1,15 @@
error[E0053]: method `bit` has an incompatible const parameter type for trait
--> $DIR/issue-86820.rs:17:18
|
LL | fn bit<const I : usize>(self) -> bool {
| ^
|
note: the const parameter `I` has type `usize`, but the declaration in trait `Bits::bit` has type `u8`
--> $DIR/issue-86820.rs:12:18
|
LL | fn bit<const I : u8>(self) -> bool;
| ^
error: aborting due to previous error
For more information about this error, try `rustc --explain E0053`.