From: flip1995 Date: Sat, 24 Feb 2018 15:40:51 +0000 (+0100) Subject: Rewrite error reporting as requested X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=5c706196449f679b163a8a5fbfb08d842db07e29;p=rust.git Rewrite error reporting as requested --- diff --git a/src/librustc_lint/types.rs b/src/librustc_lint/types.rs index db9dfedc656..02aef271c37 100644 --- a/src/librustc_lint/types.rs +++ b/src/librustc_lint/types.rs @@ -152,29 +152,14 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) { // 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 @@ fn check_expr(&mut self, cx: &LateContext<'a, 'tcx>, e: &'tcx hir::Expr) { } } 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 @@ fn get_bin_hex_repr(cx: &LateContext, lit: &ast::Lit) -> Option { // - `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 { use syntax::ast::IntTy::*; use syntax::ast::UintTy::*; macro_rules! find_fit { @@ -425,14 +400,14 @@ macro_rules! find_fit { 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,8 +425,57 @@ macro_rules! find_fit { 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(); } } } diff --git a/src/test/ui/lint/type-overflow.stderr b/src/test/ui/lint/type-overflow.stderr index 425f76da5cb..89718c7696a 100644 --- a/src/test/ui/lint/type-overflow.stderr +++ b/src/test/ui/lint/type-overflow.stderr @@ -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`