From 19840793e57e4903e00edac963f30c9de34b1ea3 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sun, 16 Sep 2018 20:03:44 +0800 Subject: [PATCH 1/6] lint to change numeric literal instead of into --- src/librustc_typeck/check/demand.rs | 90 +++++++++++++++++++++++------ 1 file changed, 72 insertions(+), 18 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 4e22ead8db987..2f80edd5433dc 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -419,6 +419,21 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { if needs_paren { "(" } else { "" }, src, if needs_paren { ")" } else { "" }); + let suffix_suggestion = format!( + "{}{}{}{}", + if needs_paren { "(" } else { "" }, + src, + expected_ty, + if needs_paren { ")" } else { "" }, + ); + + let is_suffixed = |expr: &hir::Expr| { + if let hir::ExprKind::Lit(lit) = &expr.node { + lit.node.is_suffixed() + } else { + false + } + }; match (&expected_ty.sty, &checked_ty.sty) { (&ty::Int(ref exp), &ty::Int(ref found)) => { @@ -444,12 +459,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } _ => { - err.span_suggestion_with_applicability( - expr.span, - &format!("{}, which {}", msg, will_sign_extend), - into_suggestion, - Applicability::MachineApplicable - ); + if is_suffixed(expr) { + err.span_suggestion_with_applicability( + expr.span, + &format!( + "change the type of the numeric literal from `{}` to `{}`", + checked_ty, + expected_ty, + ), + suffix_suggestion, + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_with_applicability( + expr.span, + &format!("{}, which {}", msg, will_sign_extend), + into_suggestion, + Applicability::MachineApplicable + ); + } } } true @@ -477,12 +505,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } _ => { - err.span_suggestion_with_applicability( - expr.span, - &format!("{}, which {}", msg, will_zero_extend), - into_suggestion, - Applicability::MachineApplicable - ); + if is_suffixed(expr) { + err.span_suggestion_with_applicability( + expr.span, + &format!( + "change the type of the numeric literal from `{}` to `{}`", + checked_ty, + expected_ty, + ), + suffix_suggestion, + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_with_applicability( + expr.span, + &format!("{}, which {}", msg, will_zero_extend), + into_suggestion, + Applicability::MachineApplicable + ); + } } } true @@ -583,12 +624,25 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } (&ty::Float(ref exp), &ty::Float(ref found)) => { if found.bit_width() < exp.bit_width() { - err.span_suggestion_with_applicability( - expr.span, - &format!("{} in a lossless way", msg), - into_suggestion, - Applicability::MachineApplicable - ); + if is_suffixed(expr) { + err.span_suggestion_with_applicability( + expr.span, + &format!( + "change the type of the numeric literal from `{}` to `{}`", + checked_ty, + expected_ty, + ), + suffix_suggestion, + Applicability::MaybeIncorrect, + ); + } else { + err.span_suggestion_with_applicability( + expr.span, + &format!("{} in a lossless way", msg), + into_suggestion, + Applicability::MachineApplicable + ); + } } else if can_cast { err.span_suggestion_with_applicability( expr.span, From 0ff0669b79d768dd32ceefeb76cad7332221492b Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sun, 16 Sep 2018 21:12:23 +0800 Subject: [PATCH 2/6] replace old literal in expr --- src/librustc_typeck/check/demand.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 2f80edd5433dc..25559bdec76f5 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -422,7 +422,12 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let suffix_suggestion = format!( "{}{}{}{}", if needs_paren { "(" } else { "" }, - src, + { + // 42u8 + // ^^ + let lit_offset = src.len() - checked_ty.to_string().len(); + &src[..lit_offset] + }, expected_ty, if needs_paren { ")" } else { "" }, ); From 17a28f706395bab81047c5e4fd3d903304cc5c72 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sun, 16 Sep 2018 21:13:11 +0800 Subject: [PATCH 3/6] add test for numeric literal cast --- .../ui/mismatched_types/numeric-literal-cast.rs | 15 +++++++++++++++ .../mismatched_types/numeric-literal-cast.stderr | 13 +++++++++++++ 2 files changed, 28 insertions(+) create mode 100644 src/test/ui/mismatched_types/numeric-literal-cast.rs create mode 100644 src/test/ui/mismatched_types/numeric-literal-cast.stderr diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.rs b/src/test/ui/mismatched_types/numeric-literal-cast.rs new file mode 100644 index 0000000000000..8d8c9d75973b6 --- /dev/null +++ b/src/test/ui/mismatched_types/numeric-literal-cast.rs @@ -0,0 +1,15 @@ +// Copyright 2018 The Rust Project Developers. See the COPYRIGHT +// file at the top-level directory of this distribution and at +// http://rust-lang.org/COPYRIGHT. +// +// Licensed under the Apache License, Version 2.0 or the MIT license +// , at your +// option. This file may not be copied, modified, or distributed +// except according to those terms. + +fn foo(_: u16) {} +fn main() { + foo(8u8); +} + diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.stderr b/src/test/ui/mismatched_types/numeric-literal-cast.stderr new file mode 100644 index 0000000000000..8fda824311500 --- /dev/null +++ b/src/test/ui/mismatched_types/numeric-literal-cast.stderr @@ -0,0 +1,13 @@ +error[E0308]: mismatched types + --> $DIR/numeric-literal-cast.rs:13:9 + | +LL | foo(8u8); + | ^^^ expected u16, found u8 +help: change the type of the numeric literal from `u8` to `u16` + | +LL | foo(8u16); + | ^^^^ + +error: aborting due to previous error + +For more information about this error, try `rustc --explain E0308`. From d31a2a0c603c6a7ec2a69e2b5658bcca016dbc29 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Sun, 16 Sep 2018 23:13:17 +0800 Subject: [PATCH 4/6] trim type numeric literal suffix --- src/librustc_typeck/check/demand.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index 25559bdec76f5..ebed49249499c 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -422,12 +422,7 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { let suffix_suggestion = format!( "{}{}{}{}", if needs_paren { "(" } else { "" }, - { - // 42u8 - // ^^ - let lit_offset = src.len() - checked_ty.to_string().len(); - &src[..lit_offset] - }, + src.trim_right_matches(&checked_ty.to_string()), expected_ty, if needs_paren { ")" } else { "" }, ); From 9d6c4f09c4b309fd45379996975f4075ba37258b Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Mon, 17 Sep 2018 09:24:33 +0800 Subject: [PATCH 5/6] merge into/literal suggestion for DRY --- src/librustc_typeck/check/demand.rs | 119 ++++++++++++---------------- 1 file changed, 52 insertions(+), 67 deletions(-) diff --git a/src/librustc_typeck/check/demand.rs b/src/librustc_typeck/check/demand.rs index ebed49249499c..e78cd4891a5ea 100644 --- a/src/librustc_typeck/check/demand.rs +++ b/src/librustc_typeck/check/demand.rs @@ -415,19 +415,13 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { src, if needs_paren { ")" } else { "" }, expected_ty); - let into_suggestion = format!("{}{}{}.into()", - if needs_paren { "(" } else { "" }, - src, - if needs_paren { ")" } else { "" }); - let suffix_suggestion = format!( - "{}{}{}{}", + let into_suggestion = format!( + "{}{}{}.into()", if needs_paren { "(" } else { "" }, - src.trim_right_matches(&checked_ty.to_string()), - expected_ty, + src, if needs_paren { ")" } else { "" }, ); - - let is_suffixed = |expr: &hir::Expr| { + let literal_is_ty_suffixed = |expr: &hir::Expr| { if let hir::ExprKind::Lit(lit) = &expr.node { lit.node.is_suffixed() } else { @@ -435,6 +429,42 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } }; + let into_sugg = into_suggestion.clone(); + let suggest_to_change_suffix_or_into = |err: &mut DiagnosticBuilder, + note: Option<&str>| { + let suggest_msg = if literal_is_ty_suffixed(expr) { + format!( + "change the type of the numeric literal from `{}` to `{}`", + checked_ty, + expected_ty, + ) + } else { + match note { + Some(note) => format!("{}, which {}", msg, note), + _ => format!("{} in a lossless way", msg), + } + }; + + let suffix_suggestion = format!( + "{}{}{}{}", + if needs_paren { "(" } else { "" }, + src.trim_right_matches(&checked_ty.to_string()), + expected_ty, + if needs_paren { ")" } else { "" }, + ); + + err.span_suggestion_with_applicability( + expr.span, + &suggest_msg, + if literal_is_ty_suffixed(expr) { + suffix_suggestion + } else { + into_sugg + }, + Applicability::MachineApplicable, + ); + }; + match (&expected_ty.sty, &checked_ty.sty) { (&ty::Int(ref exp), &ty::Int(ref found)) => { match (found.bit_width(), exp.bit_width()) { @@ -459,25 +489,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } _ => { - if is_suffixed(expr) { - err.span_suggestion_with_applicability( - expr.span, - &format!( - "change the type of the numeric literal from `{}` to `{}`", - checked_ty, - expected_ty, - ), - suffix_suggestion, - Applicability::MaybeIncorrect, - ); - } else { - err.span_suggestion_with_applicability( - expr.span, - &format!("{}, which {}", msg, will_sign_extend), - into_suggestion, - Applicability::MachineApplicable - ); - } + suggest_to_change_suffix_or_into( + err, + Some(will_sign_extend), + ); } } true @@ -505,25 +520,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } } _ => { - if is_suffixed(expr) { - err.span_suggestion_with_applicability( - expr.span, - &format!( - "change the type of the numeric literal from `{}` to `{}`", - checked_ty, - expected_ty, - ), - suffix_suggestion, - Applicability::MaybeIncorrect, - ); - } else { - err.span_suggestion_with_applicability( - expr.span, - &format!("{}, which {}", msg, will_zero_extend), - into_suggestion, - Applicability::MachineApplicable - ); - } + suggest_to_change_suffix_or_into( + err, + Some(will_zero_extend), + ); } } true @@ -624,25 +624,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> { } (&ty::Float(ref exp), &ty::Float(ref found)) => { if found.bit_width() < exp.bit_width() { - if is_suffixed(expr) { - err.span_suggestion_with_applicability( - expr.span, - &format!( - "change the type of the numeric literal from `{}` to `{}`", - checked_ty, - expected_ty, - ), - suffix_suggestion, - Applicability::MaybeIncorrect, - ); - } else { - err.span_suggestion_with_applicability( - expr.span, - &format!("{} in a lossless way", msg), - into_suggestion, - Applicability::MachineApplicable - ); - } + suggest_to_change_suffix_or_into( + err, + None, + ); } else if can_cast { err.span_suggestion_with_applicability( expr.span, From 2fb6585f33bf1af3b6b5143347eb534cebd257e4 Mon Sep 17 00:00:00 2001 From: csmoe <35686186+csmoe@users.noreply.github.com> Date: Mon, 17 Sep 2018 09:29:57 +0800 Subject: [PATCH 6/6] add test for float/integer --- .../mismatched_types/numeric-literal-cast.rs | 7 ++++- .../numeric-literal-cast.stderr | 28 ++++++++++++++++--- 2 files changed, 30 insertions(+), 5 deletions(-) diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.rs b/src/test/ui/mismatched_types/numeric-literal-cast.rs index 8d8c9d75973b6..516b2e8dd30bf 100644 --- a/src/test/ui/mismatched_types/numeric-literal-cast.rs +++ b/src/test/ui/mismatched_types/numeric-literal-cast.rs @@ -9,7 +9,12 @@ // except according to those terms. fn foo(_: u16) {} +fn foo1(_: f64) {} +fn foo2(_: i32) {} + fn main() { - foo(8u8); + foo(1u8); + foo1(2f32); + foo2(3i16); } diff --git a/src/test/ui/mismatched_types/numeric-literal-cast.stderr b/src/test/ui/mismatched_types/numeric-literal-cast.stderr index 8fda824311500..e2fe1a0914d4f 100644 --- a/src/test/ui/mismatched_types/numeric-literal-cast.stderr +++ b/src/test/ui/mismatched_types/numeric-literal-cast.stderr @@ -1,13 +1,33 @@ error[E0308]: mismatched types - --> $DIR/numeric-literal-cast.rs:13:9 + --> $DIR/numeric-literal-cast.rs:16:9 | -LL | foo(8u8); +LL | foo(1u8); | ^^^ expected u16, found u8 help: change the type of the numeric literal from `u8` to `u16` | -LL | foo(8u16); +LL | foo(1u16); | ^^^^ -error: aborting due to previous error +error[E0308]: mismatched types + --> $DIR/numeric-literal-cast.rs:17:10 + | +LL | foo1(2f32); + | ^^^^ expected f64, found f32 +help: change the type of the numeric literal from `f32` to `f64` + | +LL | foo1(2f64); + | ^^^^ + +error[E0308]: mismatched types + --> $DIR/numeric-literal-cast.rs:18:10 + | +LL | foo2(3i16); + | ^^^^ expected i32, found i16 +help: change the type of the numeric literal from `i16` to `i32` + | +LL | foo2(3i32); + | ^^^^ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`.