From 1f0a864570d79807c7843ebb995fdcdd384ff3c9 Mon Sep 17 00:00:00 2001 From: Samrat Man Singh Date: Tue, 28 Apr 2020 00:13:37 +0530 Subject: [PATCH 1/3] Suggest `into` instead of `try_into` if possible with int types If it is possible to convert an integer type into another using `into`, don't suggest `try_into`. This commit changes the suggested method to convert from one integer type to another for the following cases: - u{n} -> i{m} where n < m - u8 -> isize - i{n} -> isize where n <= 16 - u{n} -> usize where n <= 16 --- src/librustc_typeck/check/demand.rs | 11 +++++- src/test/ui/suggestions/integer-into.rs | 17 ++++++++ src/test/ui/suggestions/integer-into.stderr | 43 +++++++++++++++++++++ 3 files changed, 70 insertions(+), 1 deletion(-) create mode 100644 src/test/ui/suggestions/integer-into.rs create mode 100644 src/test/ui/suggestions/integer-into.stderr diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index c75283e419a6d..980aefa710ff5 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -767,7 +767,16 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { suggest_to_change_suffix_or_into(err, is_fallible); true } - (&ty::Int(_), &ty::Uint(_)) | (&ty::Uint(_), &ty::Int(_)) => { + (&ty::Int(exp), &ty::Uint(found)) => { + let is_fallible = match (exp.bit_width(), found.bit_width()) { + (Some(exp), Some(found)) if found < exp => false, + (None, Some(found)) if found <= 16 => false, + _ => true + }; + suggest_to_change_suffix_or_into(err, is_fallible); + true + }, + (&ty::Uint(_), &ty::Int(_)) => { suggest_to_change_suffix_or_into(err, true); true } diff --git a/src/test/ui/suggestions/integer-into.rs b/src/test/ui/suggestions/integer-into.rs new file mode 100644 index 0000000000000..409b27a4eab31 --- /dev/null +++ b/src/test/ui/suggestions/integer-into.rs @@ -0,0 +1,17 @@ +fn main() { + let a = 1u8; + let _: i64 = a; + //~^ ERROR mismatched types + + let b = 1i8; + let _: isize = b; + //~^ ERROR mismatched types + + let c = 1u8; + let _: isize = c; + //~^ ERROR mismatched types + + let d = 1u8; + let _: usize = d; + //~^ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/integer-into.stderr b/src/test/ui/suggestions/integer-into.stderr new file mode 100644 index 0000000000000..a15cf81f71fe7 --- /dev/null +++ b/src/test/ui/suggestions/integer-into.stderr @@ -0,0 +1,43 @@ +error[E0308]: mismatched types + --> $DIR/integer-into.rs:3:18 + | +LL | let _: i64 = a; + | --- ^ + | | | + | | expected `i64`, found `u8` + | | help: you can convert an `u8` to `i64`: `a.into()` + | expected due to this + +error[E0308]: mismatched types + --> $DIR/integer-into.rs:7:20 + | +LL | let _: isize = b; + | ----- ^ + | | | + | | expected `isize`, found `i8` + | | help: you can convert an `i8` to `isize`: `b.into()` + | expected due to this + +error[E0308]: mismatched types + --> $DIR/integer-into.rs:11:20 + | +LL | let _: isize = c; + | ----- ^ + | | | + | | expected `isize`, found `u8` + | | help: you can convert an `u8` to `isize`: `c.into()` + | expected due to this + +error[E0308]: mismatched types + --> $DIR/integer-into.rs:15:20 + | +LL | let _: usize = d; + | ----- ^ + | | | + | | expected `usize`, found `u8` + | | help: you can convert an `u8` to `usize`: `d.into()` + | expected due to this + +error: aborting due to 4 previous errors + +For more information about this error, try `rustc --explain E0308`. From 57dd22baad83d3e5a8ec81a0bf64ad54464988bc Mon Sep 17 00:00:00 2001 From: Samrat Man Singh Date: Tue, 28 Apr 2020 21:27:14 +0530 Subject: [PATCH 2/3] Suggest `into` to convert into `isize` only if uint is of width 8 Since Into is not implemented for uint of width greater than 8 --- src/librustc_typeck/check/demand.rs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 980aefa710ff5..aa36bec6e1e88 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -770,12 +770,12 @@ impl<'a, 'tcx> FnCtxt<'a, 'tcx> { (&ty::Int(exp), &ty::Uint(found)) => { let is_fallible = match (exp.bit_width(), found.bit_width()) { (Some(exp), Some(found)) if found < exp => false, - (None, Some(found)) if found <= 16 => false, - _ => true + (None, Some(8)) => false, + _ => true, }; suggest_to_change_suffix_or_into(err, is_fallible); true - }, + } (&ty::Uint(_), &ty::Int(_)) => { suggest_to_change_suffix_or_into(err, true); true From a6033e33e7199646b269c0f3504591b108670fef Mon Sep 17 00:00:00 2001 From: Samrat Man Singh Date: Tue, 28 Apr 2020 21:32:36 +0530 Subject: [PATCH 3/3] Fix numeric-cast tests for new `into` suggestion Remove `integer-into.rs` since the numeric-cast tests already cover these cases. --- src/test/ui/numeric/numeric-cast-2.stderr | 22 +++---- src/test/ui/numeric/numeric-cast.fixed | 14 ++--- src/test/ui/numeric/numeric-cast.stderr | 70 +++++++++------------ src/test/ui/suggestions/integer-into.rs | 17 ----- src/test/ui/suggestions/integer-into.stderr | 43 ------------- 5 files changed, 43 insertions(+), 123 deletions(-) delete mode 100644 src/test/ui/suggestions/integer-into.rs delete mode 100644 src/test/ui/suggestions/integer-into.stderr diff --git a/src/test/ui/numeric/numeric-cast-2.stderr b/src/test/ui/numeric/numeric-cast-2.stderr index 465b507b788fd..3f900062cbb6e 100644 --- a/src/test/ui/numeric/numeric-cast-2.stderr +++ b/src/test/ui/numeric/numeric-cast-2.stderr @@ -15,27 +15,21 @@ error[E0308]: mismatched types --> $DIR/numeric-cast-2.rs:7:18 | LL | let y: i64 = x + x; - | --- ^^^^^ expected `i64`, found `u16` - | | + | --- ^^^^^ + | | | + | | expected `i64`, found `u16` + | | help: you can convert an `u16` to `i64`: `(x + x).into()` | expected due to this - | -help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit - | -LL | let y: i64 = (x + x).try_into().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error[E0308]: mismatched types --> $DIR/numeric-cast-2.rs:9:18 | LL | let z: i32 = x + x; - | --- ^^^^^ expected `i32`, found `u16` - | | + | --- ^^^^^ + | | | + | | expected `i32`, found `u16` + | | help: you can convert an `u16` to `i32`: `(x + x).into()` | expected due to this - | -help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit - | -LL | let z: i32 = (x + x).try_into().unwrap(); - | ^^^^^^^^^^^^^^^^^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/numeric/numeric-cast.fixed b/src/test/ui/numeric/numeric-cast.fixed index 31acdb8faf6a2..cf0560a107772 100644 --- a/src/test/ui/numeric/numeric-cast.fixed +++ b/src/test/ui/numeric/numeric-cast.fixed @@ -49,7 +49,7 @@ fn main() { //~^ ERROR mismatched types foo::(x_u16.try_into().unwrap()); //~^ ERROR mismatched types - foo::(x_u8.try_into().unwrap()); + foo::(x_u8.into()); //~^ ERROR mismatched types foo::(x_isize); foo::(x_i64.try_into().unwrap()); @@ -89,11 +89,11 @@ fn main() { //~^ ERROR mismatched types foo::(x_u64.try_into().unwrap()); //~^ ERROR mismatched types - foo::(x_u32.try_into().unwrap()); + foo::(x_u32.into()); //~^ ERROR mismatched types - foo::(x_u16.try_into().unwrap()); + foo::(x_u16.into()); //~^ ERROR mismatched types - foo::(x_u8.try_into().unwrap()); + foo::(x_u8.into()); //~^ ERROR mismatched types foo::(x_isize.try_into().unwrap()); //~^ ERROR mismatched types @@ -135,9 +135,9 @@ fn main() { //~^ ERROR mismatched types foo::(x_u32.try_into().unwrap()); //~^ ERROR mismatched types - foo::(x_u16.try_into().unwrap()); + foo::(x_u16.into()); //~^ ERROR mismatched types - foo::(x_u8.try_into().unwrap()); + foo::(x_u8.into()); //~^ ERROR mismatched types foo::(x_isize.try_into().unwrap()); //~^ ERROR mismatched types @@ -181,7 +181,7 @@ fn main() { //~^ ERROR mismatched types foo::(x_u16.try_into().unwrap()); //~^ ERROR mismatched types - foo::(x_u8.try_into().unwrap()); + foo::(x_u8.into()); //~^ ERROR mismatched types foo::(x_isize.try_into().unwrap()); //~^ ERROR mismatched types diff --git a/src/test/ui/numeric/numeric-cast.stderr b/src/test/ui/numeric/numeric-cast.stderr index ff92a86c3a7b4..cc1aa72d21451 100644 --- a/src/test/ui/numeric/numeric-cast.stderr +++ b/src/test/ui/numeric/numeric-cast.stderr @@ -141,12 +141,10 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:52:18 | LL | foo::(x_u8); - | ^^^^ expected `isize`, found `u8` - | -help: you can convert an `u8` to `isize` and panic if the converted value wouldn't fit - | -LL | foo::(x_u8.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ + | | + | expected `isize`, found `u8` + | help: you can convert an `u8` to `isize`: `x_u8.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:55:18 @@ -307,34 +305,28 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:92:16 | LL | foo::(x_u32); - | ^^^^^ expected `i64`, found `u32` - | -help: you can convert an `u32` to `i64` and panic if the converted value wouldn't fit - | -LL | foo::(x_u32.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ + | | + | expected `i64`, found `u32` + | help: you can convert an `u32` to `i64`: `x_u32.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:94:16 | LL | foo::(x_u16); - | ^^^^^ expected `i64`, found `u16` - | -help: you can convert an `u16` to `i64` and panic if the converted value wouldn't fit - | -LL | foo::(x_u16.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ + | | + | expected `i64`, found `u16` + | help: you can convert an `u16` to `i64`: `x_u16.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:96:16 | LL | foo::(x_u8); - | ^^^^ expected `i64`, found `u8` - | -help: you can convert an `u8` to `i64` and panic if the converted value wouldn't fit - | -LL | foo::(x_u8.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ + | | + | expected `i64`, found `u8` + | help: you can convert an `u8` to `i64`: `x_u8.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:98:16 @@ -506,23 +498,19 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:138:16 | LL | foo::(x_u16); - | ^^^^^ expected `i32`, found `u16` - | -help: you can convert an `u16` to `i32` and panic if the converted value wouldn't fit - | -LL | foo::(x_u16.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^^ + | | + | expected `i32`, found `u16` + | help: you can convert an `u16` to `i32`: `x_u16.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:140:16 | LL | foo::(x_u8); - | ^^^^ expected `i32`, found `u8` - | -help: you can convert an `u8` to `i32` and panic if the converted value wouldn't fit - | -LL | foo::(x_u8.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ + | | + | expected `i32`, found `u8` + | help: you can convert an `u8` to `i32`: `x_u8.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:142:16 @@ -709,12 +697,10 @@ error[E0308]: mismatched types --> $DIR/numeric-cast.rs:184:16 | LL | foo::(x_u8); - | ^^^^ expected `i16`, found `u8` - | -help: you can convert an `u8` to `i16` and panic if the converted value wouldn't fit - | -LL | foo::(x_u8.try_into().unwrap()); - | ^^^^^^^^^^^^^^^^^^^^^^^^ + | ^^^^ + | | + | expected `i16`, found `u8` + | help: you can convert an `u8` to `i16`: `x_u8.into()` error[E0308]: mismatched types --> $DIR/numeric-cast.rs:186:16 diff --git a/src/test/ui/suggestions/integer-into.rs b/src/test/ui/suggestions/integer-into.rs deleted file mode 100644 index 409b27a4eab31..0000000000000 --- a/src/test/ui/suggestions/integer-into.rs +++ /dev/null @@ -1,17 +0,0 @@ -fn main() { - let a = 1u8; - let _: i64 = a; - //~^ ERROR mismatched types - - let b = 1i8; - let _: isize = b; - //~^ ERROR mismatched types - - let c = 1u8; - let _: isize = c; - //~^ ERROR mismatched types - - let d = 1u8; - let _: usize = d; - //~^ ERROR mismatched types -} diff --git a/src/test/ui/suggestions/integer-into.stderr b/src/test/ui/suggestions/integer-into.stderr deleted file mode 100644 index a15cf81f71fe7..0000000000000 --- a/src/test/ui/suggestions/integer-into.stderr +++ /dev/null @@ -1,43 +0,0 @@ -error[E0308]: mismatched types - --> $DIR/integer-into.rs:3:18 - | -LL | let _: i64 = a; - | --- ^ - | | | - | | expected `i64`, found `u8` - | | help: you can convert an `u8` to `i64`: `a.into()` - | expected due to this - -error[E0308]: mismatched types - --> $DIR/integer-into.rs:7:20 - | -LL | let _: isize = b; - | ----- ^ - | | | - | | expected `isize`, found `i8` - | | help: you can convert an `i8` to `isize`: `b.into()` - | expected due to this - -error[E0308]: mismatched types - --> $DIR/integer-into.rs:11:20 - | -LL | let _: isize = c; - | ----- ^ - | | | - | | expected `isize`, found `u8` - | | help: you can convert an `u8` to `isize`: `c.into()` - | expected due to this - -error[E0308]: mismatched types - --> $DIR/integer-into.rs:15:20 - | -LL | let _: usize = d; - | ----- ^ - | | | - | | expected `usize`, found `u8` - | | help: you can convert an `u8` to `usize`: `d.into()` - | expected due to this - -error: aborting due to 4 previous errors - -For more information about this error, try `rustc --explain E0308`.