From afbbd383ccee8b91b1d1bbdcfb0f7a906bba71f7 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 13 Jun 2020 16:22:24 -0700 Subject: 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 --- src/test/ui/numeric/numeric-cast-no-fix.rs | 22 ++++++++ src/test/ui/numeric/numeric-cast-no-fix.stderr | 74 ++++++++++++++++++++++++++ 2 files changed, 96 insertions(+) create mode 100644 src/test/ui/numeric/numeric-cast-no-fix.rs create mode 100644 src/test/ui/numeric/numeric-cast-no-fix.stderr (limited to 'src/test/ui/numeric') diff --git a/src/test/ui/numeric/numeric-cast-no-fix.rs b/src/test/ui/numeric/numeric-cast-no-fix.rs new file mode 100644 index 00000000000..8bfd8333541 --- /dev/null +++ b/src/test/ui/numeric/numeric-cast-no-fix.rs @@ -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 +} diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr new file mode 100644 index 00000000000..51e263d636f --- /dev/null +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -0,0 +1,74 @@ +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:10:15 + | +LL | x_usize > -1_isize; + | ^^^^^^^^ expected `usize`, found `isize` + | +note: `-1_isize` can never fit into `usize` + --> $DIR/numeric-cast-no-fix.rs:10:15 + | +LL | x_usize > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:12:14 + | +LL | x_u128 > -1_isize; + | ^^^^^^^^ expected `u128`, found `isize` + | +note: `-1_isize` can never fit into `u128` + --> $DIR/numeric-cast-no-fix.rs:12:14 + | +LL | x_u128 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:14:13 + | +LL | x_u64 > -1_isize; + | ^^^^^^^^ expected `u64`, found `isize` + | +note: `-1_isize` can never fit into `u64` + --> $DIR/numeric-cast-no-fix.rs:14:13 + | +LL | x_u64 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:16:13 + | +LL | x_u32 > -1_isize; + | ^^^^^^^^ expected `u32`, found `isize` + | +note: `-1_isize` can never fit into `u32` + --> $DIR/numeric-cast-no-fix.rs:16:13 + | +LL | x_u32 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:18:13 + | +LL | x_u16 > -1_isize; + | ^^^^^^^^ expected `u16`, found `isize` + | +note: `-1_isize` can never fit into `u16` + --> $DIR/numeric-cast-no-fix.rs:18:13 + | +LL | x_u16 > -1_isize; + | ^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:20:12 + | +LL | x_u8 > -1_isize; + | ^^^^^^^^ expected `u8`, found `isize` + | +help: you can convert `x_u8` from `u8` to `isize`, matching the type of `-1_isize` + | +LL | isize::from(x_u8) > -1_isize; + | ^^^^^^^^^^^^^^^^^ + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. -- cgit 1.4.1-3-g733a5