1
Fork 0

Note numeric literals that can never fit in an expected type

re https://github.com/rust-lang/rust/pull/72380#discussion_r438289385

Given the toy code

```rust
fn is_positive(n: usize) {
  n > -1_isize;
}
```

We currently get a type mismatch error like the following:

```
error[E0308]: mismatched types
 --> src/main.rs:2:9
  |
2 |     n > -1_isize;
  |         ^^^^^^^^ expected `usize`, found `isize`
  |
help: you can convert an `isize` to `usize` and panic if the converted value wouldn't fit
  |
2 |     n > (-1_isize).try_into().unwrap();
  |         ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
```

But clearly, `-1` can never fit into a `usize`, so the suggestion will
always panic. A more useful message would tell the user that the value
can never fit in the expected type:

```
error[E0308]: mismatched types
 --> test.rs:2:9
  |
2 |     n > -1_isize;
  |         ^^^^^^^^ expected `usize`, found `isize`
  |
note: `-1_isize` can never fit into `usize`
 --> test.rs:2:9
  |
2 |     n > -1_isize;
  |         ^^^^^^^^
```

Which is what this commit implements.

I only added this check for negative literals because

- Currently we can only perform such a check for literals (constant
  value propagation is outside the scope of the typechecker at this
  point)
- A lint error for out-of-range numeric literals is already emitted

IMO it makes more sense to put this check in librustc_lint, but as far
as I can tell the typecheck pass happens before the lint pass, so I've
added it here.

r? @estebank
This commit is contained in:
Ayaz Hafiz 2020-06-13 16:22:24 -07:00
parent 06e47688bf
commit afbbd383cc
No known key found for this signature in database
GPG key ID: B443F7A3030C9AED
4 changed files with 121 additions and 1 deletions

View file

@ -0,0 +1,22 @@
#[allow(unused_must_use)]
fn main() {
let x_usize: usize = 1;
let x_u128: u128 = 2;
let x_u64: u64 = 3;
let x_u32: u32 = 4;
let x_u16: u16 = 5;
let x_u8: u8 = 6;
x_usize > -1_isize;
//~^ ERROR mismatched types
x_u128 > -1_isize;
//~^ ERROR mismatched types
x_u64 > -1_isize;
//~^ ERROR mismatched types
x_u32 > -1_isize;
//~^ ERROR mismatched types
x_u16 > -1_isize;
//~^ ERROR mismatched types
x_u8 > -1_isize;
//~^ ERROR mismatched types
}