Skip to content

Commit 5f1a123

Browse files
Rollup merge of rust-lang#54273 - csmoe:lint_ty_lit, r=estebank
Suggest to change numeric literal instead of casting Closes rust-lang#54160 r? @estebank
2 parents 22d3812 + 2fb6585 commit 5f1a123

File tree

3 files changed

+113
-21
lines changed

3 files changed

+113
-21
lines changed

src/librustc_typeck/check/demand.rs

+60-21
Original file line numberDiff line numberDiff line change
@@ -415,10 +415,55 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
415415
src,
416416
if needs_paren { ")" } else { "" },
417417
expected_ty);
418-
let into_suggestion = format!("{}{}{}.into()",
419-
if needs_paren { "(" } else { "" },
420-
src,
421-
if needs_paren { ")" } else { "" });
418+
let into_suggestion = format!(
419+
"{}{}{}.into()",
420+
if needs_paren { "(" } else { "" },
421+
src,
422+
if needs_paren { ")" } else { "" },
423+
);
424+
let literal_is_ty_suffixed = |expr: &hir::Expr| {
425+
if let hir::ExprKind::Lit(lit) = &expr.node {
426+
lit.node.is_suffixed()
427+
} else {
428+
false
429+
}
430+
};
431+
432+
let into_sugg = into_suggestion.clone();
433+
let suggest_to_change_suffix_or_into = |err: &mut DiagnosticBuilder,
434+
note: Option<&str>| {
435+
let suggest_msg = if literal_is_ty_suffixed(expr) {
436+
format!(
437+
"change the type of the numeric literal from `{}` to `{}`",
438+
checked_ty,
439+
expected_ty,
440+
)
441+
} else {
442+
match note {
443+
Some(note) => format!("{}, which {}", msg, note),
444+
_ => format!("{} in a lossless way", msg),
445+
}
446+
};
447+
448+
let suffix_suggestion = format!(
449+
"{}{}{}{}",
450+
if needs_paren { "(" } else { "" },
451+
src.trim_right_matches(&checked_ty.to_string()),
452+
expected_ty,
453+
if needs_paren { ")" } else { "" },
454+
);
455+
456+
err.span_suggestion_with_applicability(
457+
expr.span,
458+
&suggest_msg,
459+
if literal_is_ty_suffixed(expr) {
460+
suffix_suggestion
461+
} else {
462+
into_sugg
463+
},
464+
Applicability::MachineApplicable,
465+
);
466+
};
422467

423468
match (&expected_ty.sty, &checked_ty.sty) {
424469
(&ty::Int(ref exp), &ty::Int(ref found)) => {
@@ -444,11 +489,9 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
444489
}
445490
}
446491
_ => {
447-
err.span_suggestion_with_applicability(
448-
expr.span,
449-
&format!("{}, which {}", msg, will_sign_extend),
450-
into_suggestion,
451-
Applicability::MachineApplicable
492+
suggest_to_change_suffix_or_into(
493+
err,
494+
Some(will_sign_extend),
452495
);
453496
}
454497
}
@@ -477,12 +520,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
477520
}
478521
}
479522
_ => {
480-
err.span_suggestion_with_applicability(
481-
expr.span,
482-
&format!("{}, which {}", msg, will_zero_extend),
483-
into_suggestion,
484-
Applicability::MachineApplicable
485-
);
523+
suggest_to_change_suffix_or_into(
524+
err,
525+
Some(will_zero_extend),
526+
);
486527
}
487528
}
488529
true
@@ -583,12 +624,10 @@ impl<'a, 'gcx, 'tcx> FnCtxt<'a, 'gcx, 'tcx> {
583624
}
584625
(&ty::Float(ref exp), &ty::Float(ref found)) => {
585626
if found.bit_width() < exp.bit_width() {
586-
err.span_suggestion_with_applicability(
587-
expr.span,
588-
&format!("{} in a lossless way", msg),
589-
into_suggestion,
590-
Applicability::MachineApplicable
591-
);
627+
suggest_to_change_suffix_or_into(
628+
err,
629+
None,
630+
);
592631
} else if can_cast {
593632
err.span_suggestion_with_applicability(
594633
expr.span,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
2+
// file at the top-level directory of this distribution and at
3+
// http://rust-lang.org/COPYRIGHT.
4+
//
5+
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
6+
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
7+
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
8+
// option. This file may not be copied, modified, or distributed
9+
// except according to those terms.
10+
11+
fn foo(_: u16) {}
12+
fn foo1(_: f64) {}
13+
fn foo2(_: i32) {}
14+
15+
fn main() {
16+
foo(1u8);
17+
foo1(2f32);
18+
foo2(3i16);
19+
}
20+
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
error[E0308]: mismatched types
2+
--> $DIR/numeric-literal-cast.rs:16:9
3+
|
4+
LL | foo(1u8);
5+
| ^^^ expected u16, found u8
6+
help: change the type of the numeric literal from `u8` to `u16`
7+
|
8+
LL | foo(1u16);
9+
| ^^^^
10+
11+
error[E0308]: mismatched types
12+
--> $DIR/numeric-literal-cast.rs:17:10
13+
|
14+
LL | foo1(2f32);
15+
| ^^^^ expected f64, found f32
16+
help: change the type of the numeric literal from `f32` to `f64`
17+
|
18+
LL | foo1(2f64);
19+
| ^^^^
20+
21+
error[E0308]: mismatched types
22+
--> $DIR/numeric-literal-cast.rs:18:10
23+
|
24+
LL | foo2(3i16);
25+
| ^^^^ expected i32, found i16
26+
help: change the type of the numeric literal from `i16` to `i32`
27+
|
28+
LL | foo2(3i32);
29+
| ^^^^
30+
31+
error: aborting due to 3 previous errors
32+
33+
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)