From afbbd383ccee8b91b1d1bbdcfb0f7a906bba71f7 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 13 Jun 2020 16:22:24 -0700 Subject: [PATCH 1/5] 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/librustc_typeck/check/demand.rs | 14 +++- src/test/ui/numeric/numeric-cast-no-fix.rs | 22 ++++++ .../ui/numeric/numeric-cast-no-fix.stderr | 74 +++++++++++++++++++ src/test/ui/repeat_count.stderr | 12 +++ 4 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/numeric/numeric-cast-no-fix.rs create mode 100644 src/test/ui/numeric/numeric-cast-no-fix.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 019b4ca66060c..7fc880b6c7c6c 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -783,6 +783,9 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { let literal_is_ty_suffixed = |expr: &hir::Expr<'_>| { if let hir::ExprKind::Lit(lit) = &expr.kind { lit.node.is_suffixed() } else { false } }; + let is_negative_int = + |expr: &hir::Expr<'_>| matches!(expr.kind, hir::ExprKind::Unary(hir::UnOp::UnNeg, ..)); + let is_uint = |ty: Ty<'_>| matches!(ty.kind, ty::Uint(..)); let in_const_context = self.tcx.hir().is_inside_const_context(expr.hir_id); @@ -807,7 +810,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { "you can convert `{}` from `{}` to `{}`, matching the type of `{}`", lhs_src, expected_ty, checked_ty, src ); - let suggestion = format!("{}::from({})", checked_ty, lhs_src,); + let suggestion = format!("{}::from({})", checked_ty, lhs_src); (lhs_expr.span, msg, suggestion) } else { let msg = format!("{} and panic if the converted value wouldn't fit", msg); @@ -822,8 +825,17 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { |err: &mut DiagnosticBuilder<'_>, found_to_exp_is_fallible: bool, exp_to_found_is_fallible: bool| { + let always_fallible = found_to_exp_is_fallible + && (exp_to_found_is_fallible || expected_ty_expr.is_none()); let msg = if literal_is_ty_suffixed(expr) { &lit_msg + } else if always_fallible && (is_negative_int(expr) && is_uint(expected_ty)) { + // We now know that converting either the lhs or rhs is fallible. Before we + // suggest a fallible conversion, check if the value can never fit in the + // expected type. + let msg = format!("`{}` can never fit into `{}`", src, expected_ty); + err.span_note(expr.span, &msg); + return; } else if in_const_context { // Do not recommend `into` or `try_into` in const contexts. return; 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 0000000000000..8bfd833354164 --- /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 0000000000000..51e263d636f98 --- /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`. diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index 6a081e23d9d37..a1d5b36931dac 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -39,12 +39,24 @@ error[E0308]: mismatched types | LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` + | +note: `-4_isize` can never fit into `usize` + --> $DIR/repeat_count.rs:19:17 + | +LL | let f = [0; -4_isize]; + | ^^^^^^^^ error[E0308]: mismatched types --> $DIR/repeat_count.rs:22:23 | LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` + | +note: `-1_isize` can never fit into `usize` + --> $DIR/repeat_count.rs:22:23 + | +LL | let f = [0_usize; -1_isize]; + | ^^^^^^^^ error[E0308]: mismatched types --> $DIR/repeat_count.rs:25:17 From 2b936bb5a26f1f10daa5a6c5ed546dd274995942 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Sat, 13 Jun 2020 22:31:31 -0700 Subject: [PATCH 2/5] fixup! Note numeric literals that can never fit in an expected type --- src/librustc_typeck/check/demand.rs | 2 +- src/test/ui/numeric/numeric-cast-no-fix.stderr | 10 +++++----- src/test/ui/repeat_count.stderr | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 7fc880b6c7c6c..79fc9772423fd 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -833,7 +833,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // We now know that converting either the lhs or rhs is fallible. Before we // suggest a fallible conversion, check if the value can never fit in the // expected type. - let msg = format!("`{}` can never fit into `{}`", src, expected_ty); + let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty); err.span_note(expr.span, &msg); return; } else if in_const_context { diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr index 51e263d636f98..63b563aafb6de 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.stderr +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -4,7 +4,7 @@ error[E0308]: mismatched types LL | x_usize > -1_isize; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` can never fit into `usize` +note: `-1_isize` cannot fit into type `usize` --> $DIR/numeric-cast-no-fix.rs:10:15 | LL | x_usize > -1_isize; @@ -16,7 +16,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_isize; | ^^^^^^^^ expected `u128`, found `isize` | -note: `-1_isize` can never fit into `u128` +note: `-1_isize` cannot fit into type `u128` --> $DIR/numeric-cast-no-fix.rs:12:14 | LL | x_u128 > -1_isize; @@ -28,7 +28,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_isize; | ^^^^^^^^ expected `u64`, found `isize` | -note: `-1_isize` can never fit into `u64` +note: `-1_isize` cannot fit into type `u64` --> $DIR/numeric-cast-no-fix.rs:14:13 | LL | x_u64 > -1_isize; @@ -40,7 +40,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_isize; | ^^^^^^^^ expected `u32`, found `isize` | -note: `-1_isize` can never fit into `u32` +note: `-1_isize` cannot fit into type `u32` --> $DIR/numeric-cast-no-fix.rs:16:13 | LL | x_u32 > -1_isize; @@ -52,7 +52,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_isize; | ^^^^^^^^ expected `u16`, found `isize` | -note: `-1_isize` can never fit into `u16` +note: `-1_isize` cannot fit into type `u16` --> $DIR/numeric-cast-no-fix.rs:18:13 | LL | x_u16 > -1_isize; diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index a1d5b36931dac..34641be22150f 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -40,7 +40,7 @@ error[E0308]: mismatched types LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-4_isize` can never fit into `usize` +note: `-4_isize` cannot fit into type `usize` --> $DIR/repeat_count.rs:19:17 | LL | let f = [0; -4_isize]; @@ -52,7 +52,7 @@ error[E0308]: mismatched types LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` can never fit into `usize` +note: `-1_isize` cannot fit into type `usize` --> $DIR/repeat_count.rs:22:23 | LL | let f = [0_usize; -1_isize]; From f0d36891b6681c0833747d6188f0b194aee7fac8 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 16 Jun 2020 06:55:24 -0700 Subject: [PATCH 3/5] fixup! Note numeric literals that can never fit in an expected type --- src/test/ui/numeric/numeric-cast-no-fix.rs | 65 ++++ .../ui/numeric/numeric-cast-no-fix.stderr | 352 +++++++++++++++++- 2 files changed, 416 insertions(+), 1 deletion(-) diff --git a/src/test/ui/numeric/numeric-cast-no-fix.rs b/src/test/ui/numeric/numeric-cast-no-fix.rs index 8bfd833354164..63e5f098a25d3 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.rs +++ b/src/test/ui/numeric/numeric-cast-no-fix.rs @@ -19,4 +19,69 @@ fn main() { //~^ ERROR mismatched types x_u8 > -1_isize; //~^ ERROR mismatched types + + x_usize > -1_i128; + //~^ ERROR mismatched types + x_u128 > -1_i128; + //~^ ERROR mismatched types + x_u64 > -1_i128; + //~^ ERROR mismatched types + x_u32 > -1_i128; + //~^ ERROR mismatched types + x_u16 > -1_i128; + //~^ ERROR mismatched types + x_u8 > -1_i128; + //~^ ERROR mismatched types + + x_usize > -1_i64; + //~^ ERROR mismatched types + x_u128 > -1_i64; + //~^ ERROR mismatched types + x_u64 > -1_i64; + //~^ ERROR mismatched types + x_u32 > -1_i64; + //~^ ERROR mismatched types + x_u16 > -1_i64; + //~^ ERROR mismatched types + x_u8 > -1_i64; + //~^ ERROR mismatched types + + x_usize > -1_i32; + //~^ ERROR mismatched types + x_u128 > -1_i32; + //~^ ERROR mismatched types + x_u64 > -1_i32; + //~^ ERROR mismatched types + x_u32 > -1_i32; + //~^ ERROR mismatched types + x_u16 > -1_i32; + //~^ ERROR mismatched types + x_u8 > -1_i32; + //~^ ERROR mismatched types + + x_usize > -1_i16; + //~^ ERROR mismatched types + x_u128 > -1_i16; + //~^ ERROR mismatched types + x_u64 > -1_i16; + //~^ ERROR mismatched types + x_u32 > -1_i16; + //~^ ERROR mismatched types + x_u16 > -1_i16; + //~^ ERROR mismatched types + x_u8 > -1_i16; + //~^ ERROR mismatched types + + x_usize > -1_i8; + //~^ ERROR mismatched types + x_u128 > -1_i8; + //~^ ERROR mismatched types + x_u64 > -1_i8; + //~^ ERROR mismatched types + x_u32 > -1_i8; + //~^ ERROR mismatched types + x_u16 > -1_i8; + //~^ ERROR mismatched types + x_u8 > -1_i8; + //~^ 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 index 63b563aafb6de..6501e11fc64d6 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.stderr +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -69,6 +69,356 @@ help: you can convert `x_u8` from `u8` to `isize`, matching the type of `-1_isiz LL | isize::from(x_u8) > -1_isize; | ^^^^^^^^^^^^^^^^^ -error: aborting due to 6 previous errors +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:23:15 + | +LL | x_usize > -1_i128; + | ^^^^^^^ expected `usize`, found `i128` + | +note: `-1_i128` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:23:15 + | +LL | x_usize > -1_i128; + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:25:14 + | +LL | x_u128 > -1_i128; + | ^^^^^^^ expected `u128`, found `i128` + | +note: `-1_i128` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:25:14 + | +LL | x_u128 > -1_i128; + | ^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:27:13 + | +LL | x_u64 > -1_i128; + | ^^^^^^^ expected `u64`, found `i128` + | +help: you can convert `x_u64` from `u64` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u64) > -1_i128; + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:29:13 + | +LL | x_u32 > -1_i128; + | ^^^^^^^ expected `u32`, found `i128` + | +help: you can convert `x_u32` from `u32` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u32) > -1_i128; + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:31:13 + | +LL | x_u16 > -1_i128; + | ^^^^^^^ expected `u16`, found `i128` + | +help: you can convert `x_u16` from `u16` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u16) > -1_i128; + | ^^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:33:12 + | +LL | x_u8 > -1_i128; + | ^^^^^^^ expected `u8`, found `i128` + | +help: you can convert `x_u8` from `u8` to `i128`, matching the type of `-1_i128` + | +LL | i128::from(x_u8) > -1_i128; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:36:15 + | +LL | x_usize > -1_i64; + | ^^^^^^ expected `usize`, found `i64` + | +note: `-1_i64` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:36:15 + | +LL | x_usize > -1_i64; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:38:14 + | +LL | x_u128 > -1_i64; + | ^^^^^^ expected `u128`, found `i64` + | +note: `-1_i64` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:38:14 + | +LL | x_u128 > -1_i64; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:40:13 + | +LL | x_u64 > -1_i64; + | ^^^^^^ expected `u64`, found `i64` + | +note: `-1_i64` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:40:13 + | +LL | x_u64 > -1_i64; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:42:13 + | +LL | x_u32 > -1_i64; + | ^^^^^^ expected `u32`, found `i64` + | +help: you can convert `x_u32` from `u32` to `i64`, matching the type of `-1_i64` + | +LL | i64::from(x_u32) > -1_i64; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:44:13 + | +LL | x_u16 > -1_i64; + | ^^^^^^ expected `u16`, found `i64` + | +help: you can convert `x_u16` from `u16` to `i64`, matching the type of `-1_i64` + | +LL | i64::from(x_u16) > -1_i64; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:46:12 + | +LL | x_u8 > -1_i64; + | ^^^^^^ expected `u8`, found `i64` + | +help: you can convert `x_u8` from `u8` to `i64`, matching the type of `-1_i64` + | +LL | i64::from(x_u8) > -1_i64; + | ^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:49:15 + | +LL | x_usize > -1_i32; + | ^^^^^^ expected `usize`, found `i32` + | +note: `-1_i32` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:49:15 + | +LL | x_usize > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:51:14 + | +LL | x_u128 > -1_i32; + | ^^^^^^ expected `u128`, found `i32` + | +note: `-1_i32` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:51:14 + | +LL | x_u128 > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:53:13 + | +LL | x_u64 > -1_i32; + | ^^^^^^ expected `u64`, found `i32` + | +note: `-1_i32` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:53:13 + | +LL | x_u64 > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:55:13 + | +LL | x_u32 > -1_i32; + | ^^^^^^ expected `u32`, found `i32` + | +note: `-1_i32` cannot fit into type `u32` + --> $DIR/numeric-cast-no-fix.rs:55:13 + | +LL | x_u32 > -1_i32; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:57:13 + | +LL | x_u16 > -1_i32; + | ^^^^^^ expected `u16`, found `i32` + | +help: you can convert `x_u16` from `u16` to `i32`, matching the type of `-1_i32` + | +LL | i32::from(x_u16) > -1_i32; + | ^^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:59:12 + | +LL | x_u8 > -1_i32; + | ^^^^^^ expected `u8`, found `i32` + | +help: you can convert `x_u8` from `u8` to `i32`, matching the type of `-1_i32` + | +LL | i32::from(x_u8) > -1_i32; + | ^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:62:15 + | +LL | x_usize > -1_i16; + | ^^^^^^ expected `usize`, found `i16` + | +note: `-1_i16` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:62:15 + | +LL | x_usize > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:64:14 + | +LL | x_u128 > -1_i16; + | ^^^^^^ expected `u128`, found `i16` + | +note: `-1_i16` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:64:14 + | +LL | x_u128 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:66:13 + | +LL | x_u64 > -1_i16; + | ^^^^^^ expected `u64`, found `i16` + | +note: `-1_i16` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:66:13 + | +LL | x_u64 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:68:13 + | +LL | x_u32 > -1_i16; + | ^^^^^^ expected `u32`, found `i16` + | +note: `-1_i16` cannot fit into type `u32` + --> $DIR/numeric-cast-no-fix.rs:68:13 + | +LL | x_u32 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:70:13 + | +LL | x_u16 > -1_i16; + | ^^^^^^ expected `u16`, found `i16` + | +note: `-1_i16` cannot fit into type `u16` + --> $DIR/numeric-cast-no-fix.rs:70:13 + | +LL | x_u16 > -1_i16; + | ^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:72:12 + | +LL | x_u8 > -1_i16; + | ^^^^^^ expected `u8`, found `i16` + | +help: you can convert `x_u8` from `u8` to `i16`, matching the type of `-1_i16` + | +LL | i16::from(x_u8) > -1_i16; + | ^^^^^^^^^^^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:75:15 + | +LL | x_usize > -1_i8; + | ^^^^^ expected `usize`, found `i8` + | +note: `-1_i8` cannot fit into type `usize` + --> $DIR/numeric-cast-no-fix.rs:75:15 + | +LL | x_usize > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:77:14 + | +LL | x_u128 > -1_i8; + | ^^^^^ expected `u128`, found `i8` + | +note: `-1_i8` cannot fit into type `u128` + --> $DIR/numeric-cast-no-fix.rs:77:14 + | +LL | x_u128 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:79:13 + | +LL | x_u64 > -1_i8; + | ^^^^^ expected `u64`, found `i8` + | +note: `-1_i8` cannot fit into type `u64` + --> $DIR/numeric-cast-no-fix.rs:79:13 + | +LL | x_u64 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:81:13 + | +LL | x_u32 > -1_i8; + | ^^^^^ expected `u32`, found `i8` + | +note: `-1_i8` cannot fit into type `u32` + --> $DIR/numeric-cast-no-fix.rs:81:13 + | +LL | x_u32 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:83:13 + | +LL | x_u16 > -1_i8; + | ^^^^^ expected `u16`, found `i8` + | +note: `-1_i8` cannot fit into type `u16` + --> $DIR/numeric-cast-no-fix.rs:83:13 + | +LL | x_u16 > -1_i8; + | ^^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-cast-no-fix.rs:85:12 + | +LL | x_u8 > -1_i8; + | ^^^^^ expected `u8`, found `i8` + | +note: `-1_i8` cannot fit into type `u8` + --> $DIR/numeric-cast-no-fix.rs:85:12 + | +LL | x_u8 > -1_i8; + | ^^^^^ + +error: aborting due to 36 previous errors For more information about this error, try `rustc --explain E0308`. From d7277df3acc47d3bcf9e580e8991e0ebb7e66664 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 16 Jun 2020 20:05:55 -0700 Subject: [PATCH 4/5] fixup! Note numeric literals that can never fit in an expected type --- src/librustc_typeck/check/demand.rs | 2 +- .../ui/numeric/numeric-cast-no-fix.stderr | 150 +++--------------- 2 files changed, 26 insertions(+), 126 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 79fc9772423fd..bcfc0cf347cbc 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -834,7 +834,7 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { // suggest a fallible conversion, check if the value can never fit in the // expected type. let msg = format!("`{}` cannot fit into type `{}`", src, expected_ty); - err.span_note(expr.span, &msg); + err.note(&msg); return; } else if in_const_context { // Do not recommend `into` or `try_into` in const contexts. diff --git a/src/test/ui/numeric/numeric-cast-no-fix.stderr b/src/test/ui/numeric/numeric-cast-no-fix.stderr index 6501e11fc64d6..4852e7047b47a 100644 --- a/src/test/ui/numeric/numeric-cast-no-fix.stderr +++ b/src/test/ui/numeric/numeric-cast-no-fix.stderr @@ -4,11 +4,7 @@ error[E0308]: mismatched types LL | x_usize > -1_isize; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:10:15 - | -LL | x_usize > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:12:14 @@ -16,11 +12,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_isize; | ^^^^^^^^ expected `u128`, found `isize` | -note: `-1_isize` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:12:14 - | -LL | x_u128 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:14:13 @@ -28,11 +20,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_isize; | ^^^^^^^^ expected `u64`, found `isize` | -note: `-1_isize` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:14:13 - | -LL | x_u64 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:16:13 @@ -40,11 +28,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_isize; | ^^^^^^^^ expected `u32`, found `isize` | -note: `-1_isize` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:16:13 - | -LL | x_u32 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:18:13 @@ -52,11 +36,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_isize; | ^^^^^^^^ expected `u16`, found `isize` | -note: `-1_isize` cannot fit into type `u16` - --> $DIR/numeric-cast-no-fix.rs:18:13 - | -LL | x_u16 > -1_isize; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `u16` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:20:12 @@ -75,11 +55,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i128; | ^^^^^^^ expected `usize`, found `i128` | -note: `-1_i128` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:23:15 - | -LL | x_usize > -1_i128; - | ^^^^^^^ + = note: `-1_i128` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:25:14 @@ -87,11 +63,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i128; | ^^^^^^^ expected `u128`, found `i128` | -note: `-1_i128` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:25:14 - | -LL | x_u128 > -1_i128; - | ^^^^^^^ + = note: `-1_i128` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:27:13 @@ -143,11 +115,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i64; | ^^^^^^ expected `usize`, found `i64` | -note: `-1_i64` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:36:15 - | -LL | x_usize > -1_i64; - | ^^^^^^ + = note: `-1_i64` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:38:14 @@ -155,11 +123,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i64; | ^^^^^^ expected `u128`, found `i64` | -note: `-1_i64` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:38:14 - | -LL | x_u128 > -1_i64; - | ^^^^^^ + = note: `-1_i64` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:40:13 @@ -167,11 +131,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i64; | ^^^^^^ expected `u64`, found `i64` | -note: `-1_i64` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:40:13 - | -LL | x_u64 > -1_i64; - | ^^^^^^ + = note: `-1_i64` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:42:13 @@ -212,11 +172,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i32; | ^^^^^^ expected `usize`, found `i32` | -note: `-1_i32` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:49:15 - | -LL | x_usize > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:51:14 @@ -224,11 +180,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i32; | ^^^^^^ expected `u128`, found `i32` | -note: `-1_i32` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:51:14 - | -LL | x_u128 > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:53:13 @@ -236,11 +188,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i32; | ^^^^^^ expected `u64`, found `i32` | -note: `-1_i32` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:53:13 - | -LL | x_u64 > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:55:13 @@ -248,11 +196,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_i32; | ^^^^^^ expected `u32`, found `i32` | -note: `-1_i32` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:55:13 - | -LL | x_u32 > -1_i32; - | ^^^^^^ + = note: `-1_i32` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:57:13 @@ -282,11 +226,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i16; | ^^^^^^ expected `usize`, found `i16` | -note: `-1_i16` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:62:15 - | -LL | x_usize > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:64:14 @@ -294,11 +234,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i16; | ^^^^^^ expected `u128`, found `i16` | -note: `-1_i16` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:64:14 - | -LL | x_u128 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:66:13 @@ -306,11 +242,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i16; | ^^^^^^ expected `u64`, found `i16` | -note: `-1_i16` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:66:13 - | -LL | x_u64 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:68:13 @@ -318,11 +250,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_i16; | ^^^^^^ expected `u32`, found `i16` | -note: `-1_i16` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:68:13 - | -LL | x_u32 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:70:13 @@ -330,11 +258,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_i16; | ^^^^^^ expected `u16`, found `i16` | -note: `-1_i16` cannot fit into type `u16` - --> $DIR/numeric-cast-no-fix.rs:70:13 - | -LL | x_u16 > -1_i16; - | ^^^^^^ + = note: `-1_i16` cannot fit into type `u16` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:72:12 @@ -353,11 +277,7 @@ error[E0308]: mismatched types LL | x_usize > -1_i8; | ^^^^^ expected `usize`, found `i8` | -note: `-1_i8` cannot fit into type `usize` - --> $DIR/numeric-cast-no-fix.rs:75:15 - | -LL | x_usize > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:77:14 @@ -365,11 +285,7 @@ error[E0308]: mismatched types LL | x_u128 > -1_i8; | ^^^^^ expected `u128`, found `i8` | -note: `-1_i8` cannot fit into type `u128` - --> $DIR/numeric-cast-no-fix.rs:77:14 - | -LL | x_u128 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u128` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:79:13 @@ -377,11 +293,7 @@ error[E0308]: mismatched types LL | x_u64 > -1_i8; | ^^^^^ expected `u64`, found `i8` | -note: `-1_i8` cannot fit into type `u64` - --> $DIR/numeric-cast-no-fix.rs:79:13 - | -LL | x_u64 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u64` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:81:13 @@ -389,11 +301,7 @@ error[E0308]: mismatched types LL | x_u32 > -1_i8; | ^^^^^ expected `u32`, found `i8` | -note: `-1_i8` cannot fit into type `u32` - --> $DIR/numeric-cast-no-fix.rs:81:13 - | -LL | x_u32 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u32` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:83:13 @@ -401,11 +309,7 @@ error[E0308]: mismatched types LL | x_u16 > -1_i8; | ^^^^^ expected `u16`, found `i8` | -note: `-1_i8` cannot fit into type `u16` - --> $DIR/numeric-cast-no-fix.rs:83:13 - | -LL | x_u16 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u16` error[E0308]: mismatched types --> $DIR/numeric-cast-no-fix.rs:85:12 @@ -413,11 +317,7 @@ error[E0308]: mismatched types LL | x_u8 > -1_i8; | ^^^^^ expected `u8`, found `i8` | -note: `-1_i8` cannot fit into type `u8` - --> $DIR/numeric-cast-no-fix.rs:85:12 - | -LL | x_u8 > -1_i8; - | ^^^^^ + = note: `-1_i8` cannot fit into type `u8` error: aborting due to 36 previous errors From 7a89a338239c0d551279b9183b9c2c1a1e7d7e74 Mon Sep 17 00:00:00 2001 From: Ayaz Hafiz Date: Tue, 16 Jun 2020 23:10:41 -0700 Subject: [PATCH 5/5] fixup! Note numeric literals that can never fit in an expected type --- src/test/ui/repeat_count.stderr | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/src/test/ui/repeat_count.stderr b/src/test/ui/repeat_count.stderr index 34641be22150f..2eab3ebc7687d 100644 --- a/src/test/ui/repeat_count.stderr +++ b/src/test/ui/repeat_count.stderr @@ -40,11 +40,7 @@ error[E0308]: mismatched types LL | let f = [0; -4_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-4_isize` cannot fit into type `usize` - --> $DIR/repeat_count.rs:19:17 - | -LL | let f = [0; -4_isize]; - | ^^^^^^^^ + = note: `-4_isize` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/repeat_count.rs:22:23 @@ -52,11 +48,7 @@ error[E0308]: mismatched types LL | let f = [0_usize; -1_isize]; | ^^^^^^^^ expected `usize`, found `isize` | -note: `-1_isize` cannot fit into type `usize` - --> $DIR/repeat_count.rs:22:23 - | -LL | let f = [0_usize; -1_isize]; - | ^^^^^^^^ + = note: `-1_isize` cannot fit into type `usize` error[E0308]: mismatched types --> $DIR/repeat_count.rs:25:17