Rewrite error reporting as requested
This commit is contained in:
parent
19c4771eeb
commit
5c70619644
2 changed files with 82 additions and 62 deletions
|
|
@ -152,29 +152,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
|
|||
// avoiding use of -min to prevent overflow/panic
|
||||
if (negative && v > max + 1) || (!negative && v > max) {
|
||||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
let bits = int_ty_bits(t, cx.sess().target.isize_ty);
|
||||
let actually =
|
||||
((v << (128 - bits)) as i128) >> (128 - bits);
|
||||
let mut err = cx.struct_span_lint(
|
||||
OVERFLOWING_LITERALS,
|
||||
e.span,
|
||||
&format!("literal out of range for {:?}", t),
|
||||
);
|
||||
err.note(&format!(
|
||||
"the literal `{}` (decimal `{}`) does not fit into \
|
||||
an `{:?}` and will become `{}{:?}`.",
|
||||
repr_str, v, t, actually, t
|
||||
));
|
||||
let sugg_ty = get_type_suggestion(
|
||||
&cx.tables.node_id_to_type(e.hir_id).sty,
|
||||
report_bin_hex_error(
|
||||
cx,
|
||||
e,
|
||||
ty::TyInt(t),
|
||||
repr_str,
|
||||
v,
|
||||
negative,
|
||||
);
|
||||
if !sugg_ty.is_empty() {
|
||||
err.help(&sugg_ty);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
cx.span_lint(
|
||||
|
|
@ -219,28 +204,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
|
|||
}
|
||||
}
|
||||
if let Some(repr_str) = get_bin_hex_repr(cx, lit) {
|
||||
let bits = uint_ty_bits(t, cx.sess().target.usize_ty);
|
||||
let actually = (lit_val << (128 - bits)) >> (128 - bits);
|
||||
let mut err = cx.struct_span_lint(
|
||||
OVERFLOWING_LITERALS,
|
||||
e.span,
|
||||
&format!("literal out of range for {:?}", t),
|
||||
);
|
||||
err.note(&format!(
|
||||
"the literal `{}` (decimal `{}`) does not fit into \
|
||||
an `{:?}` and will become `{}{:?}`.",
|
||||
repr_str, lit_val, t, actually, t
|
||||
));
|
||||
let sugg_ty = get_type_suggestion(
|
||||
&cx.tables.node_id_to_type(e.hir_id).sty,
|
||||
report_bin_hex_error(
|
||||
cx,
|
||||
e,
|
||||
ty::TyUint(t),
|
||||
repr_str,
|
||||
lit_val,
|
||||
false,
|
||||
);
|
||||
if !sugg_ty.is_empty() {
|
||||
err.help(&sugg_ty);
|
||||
}
|
||||
|
||||
err.emit();
|
||||
return;
|
||||
}
|
||||
cx.span_lint(
|
||||
|
|
@ -414,7 +385,11 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
|
|||
// - `uX` => `uY`
|
||||
//
|
||||
// No suggestion for: `isize`, `usize`.
|
||||
fn get_type_suggestion<'a>(t: &ty::TypeVariants, val: u128, negative: bool) -> String {
|
||||
fn get_type_suggestion<'a>(
|
||||
t: &ty::TypeVariants,
|
||||
val: u128,
|
||||
negative: bool,
|
||||
) -> Option<String> {
|
||||
use syntax::ast::IntTy::*;
|
||||
use syntax::ast::UintTy::*;
|
||||
macro_rules! find_fit {
|
||||
|
|
@ -425,14 +400,14 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
|
|||
match $ty {
|
||||
$($type => {
|
||||
$(if !negative && val <= uint_ty_range($utypes).1 {
|
||||
return format!("Consider using `{:?}`", $utypes)
|
||||
return Some(format!("{:?}", $utypes))
|
||||
})*
|
||||
$(if val <= int_ty_range($itypes).1 as u128 + _neg {
|
||||
return format!("Consider using `{:?}`", $itypes)
|
||||
return Some(format!("{:?}", $itypes))
|
||||
})*
|
||||
String::new()
|
||||
None
|
||||
},)*
|
||||
_ => String::new()
|
||||
_ => None
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -450,9 +425,58 @@ impl<'a, 'tcx> LateLintPass<'a, 'tcx> for TypeLimits {
|
|||
U32 => [U32, U64, U128] => [],
|
||||
U64 => [U64, U128] => [],
|
||||
U128 => [U128] => []),
|
||||
_ => String::new(),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
||||
fn report_bin_hex_error(
|
||||
cx: &LateContext,
|
||||
expr: &hir::Expr,
|
||||
ty: ty::TypeVariants,
|
||||
repr_str: String,
|
||||
val: u128,
|
||||
negative: bool,
|
||||
) {
|
||||
let (t, actually) = match ty {
|
||||
ty::TyInt(t) => {
|
||||
let bits = int_ty_bits(t, cx.sess().target.isize_ty);
|
||||
let actually = (val << (128 - bits)) as i128 >> (128 - bits);
|
||||
(format!("{:?}", t), actually.to_string())
|
||||
}
|
||||
ty::TyUint(t) => {
|
||||
let bits = uint_ty_bits(t, cx.sess().target.usize_ty);
|
||||
let actually = (val << (128 - bits)) >> (128 - bits);
|
||||
(format!("{:?}", t), actually.to_string())
|
||||
}
|
||||
_ => bug!(),
|
||||
};
|
||||
let mut err = cx.struct_span_lint(
|
||||
OVERFLOWING_LITERALS,
|
||||
expr.span,
|
||||
&format!("literal out of range for {}", t),
|
||||
);
|
||||
err.note(&format!(
|
||||
"the literal `{}` (decimal `{}`) does not fit into \
|
||||
an `{}` and will become `{}{}`",
|
||||
repr_str, val, t, actually, t
|
||||
));
|
||||
if let Some(sugg_ty) =
|
||||
get_type_suggestion(&cx.tables.node_id_to_type(expr.hir_id).sty, val, negative)
|
||||
{
|
||||
if let Some(pos) = repr_str.chars().position(|c| c == 'i' || c == 'u') {
|
||||
let (sans_suffix, _) = repr_str.split_at(pos);
|
||||
err.span_suggestion(
|
||||
expr.span,
|
||||
&format!("consider using `{}` instead", sugg_ty),
|
||||
format!("{}{}", sans_suffix, sugg_ty),
|
||||
);
|
||||
} else {
|
||||
err.help(&format!("consider using `{}` instead", sugg_ty));
|
||||
}
|
||||
}
|
||||
|
||||
err.emit();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,28 +10,25 @@ warning: literal out of range for i8
|
|||
--> $DIR/type-overflow.rs:21:16
|
||||
|
|
||||
21 | let fail = 0b1000_0001i8; //~WARNING literal out of range for i8
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^ help: consider using `u8` instead: `0b1000_0001u8`
|
||||
|
|
||||
= note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8`.
|
||||
= help: Consider using `u8`
|
||||
= note: the literal `0b1000_0001i8` (decimal `129`) does not fit into an `i8` and will become `-127i8`
|
||||
|
||||
warning: literal out of range for i64
|
||||
--> $DIR/type-overflow.rs:23:16
|
||||
|
|
||||
23 | let fail = 0x8000_0000_0000_0000i64; //~WARNING literal out of range for i64
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x8000_0000_0000_0000u64`
|
||||
|
|
||||
= note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64`.
|
||||
= help: Consider using `u64`
|
||||
= note: the literal `0x8000_0000_0000_0000i64` (decimal `9223372036854775808`) does not fit into an `i64` and will become `-9223372036854775808i64`
|
||||
|
||||
warning: literal out of range for u32
|
||||
--> $DIR/type-overflow.rs:25:16
|
||||
|
|
||||
25 | let fail = 0x1_FFFF_FFFFu32; //~WARNING literal out of range for u32
|
||||
| ^^^^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^^^^ help: consider using `u64` instead: `0x1_FFFF_FFFFu64`
|
||||
|
|
||||
= note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32`.
|
||||
= help: Consider using `u64`
|
||||
= note: the literal `0x1_FFFF_FFFFu32` (decimal `8589934591`) does not fit into an `u32` and will become `4294967295u32`
|
||||
|
||||
warning: literal out of range for i128
|
||||
--> $DIR/type-overflow.rs:27:22
|
||||
|
|
@ -39,8 +36,8 @@ warning: literal out of range for i128
|
|||
27 | let fail: i128 = 0x8000_0000_0000_0000_0000_0000_0000_0000;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128`.
|
||||
= help: Consider using `u128`
|
||||
= note: the literal `0x8000_0000_0000_0000_0000_0000_0000_0000` (decimal `170141183460469231731687303715884105728`) does not fit into an `i128` and will become `-170141183460469231731687303715884105728i128`
|
||||
= help: consider using `u128` instead
|
||||
|
||||
warning: literal out of range for i32
|
||||
--> $DIR/type-overflow.rs:30:16
|
||||
|
|
@ -48,8 +45,8 @@ warning: literal out of range for i32
|
|||
30 | let fail = 0x8FFF_FFFF_FFFF_FFFE; //~WARNING literal out of range for i32
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32`.
|
||||
= help: Consider using `i128`
|
||||
= note: the literal `0x8FFF_FFFF_FFFF_FFFE` (decimal `10376293541461622782`) does not fit into an `i32` and will become `-2i32`
|
||||
= help: consider using `i128` instead
|
||||
|
||||
warning: literal out of range for isize
|
||||
--> $DIR/type-overflow.rs:32:23
|
||||
|
|
@ -57,14 +54,13 @@ warning: literal out of range for isize
|
|||
32 | let fail: isize = 0x8000_0000_0000_0000; //~WARNING literal out of range for isize
|
||||
| ^^^^^^^^^^^^^^^^^^^^^
|
||||
|
|
||||
= note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize`.
|
||||
= note: the literal `0x8000_0000_0000_0000` (decimal `9223372036854775808`) does not fit into an `isize` and will become `-9223372036854775808isize`
|
||||
|
||||
warning: literal out of range for i8
|
||||
--> $DIR/type-overflow.rs:34:17
|
||||
|
|
||||
34 | let fail = -0b1111_1111i8; //~WARNING literal out of range for i8
|
||||
| ^^^^^^^^^^^^^
|
||||
| ^^^^^^^^^^^^^ help: consider using `i16` instead: `0b1111_1111i16`
|
||||
|
|
||||
= note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`.
|
||||
= help: Consider using `i16`
|
||||
= note: the literal `0b1111_1111i8` (decimal `255`) does not fit into an `i8` and will become `-1i8`
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue