]> git.lizzy.rs Git - rust.git/commitdiff
Rewrite error reporting as requested
authorflip1995 <uwdkn@student.kit.edu>
Sat, 24 Feb 2018 15:40:51 +0000 (16:40 +0100)
committerflip1995 <uwdkn@student.kit.edu>
Thu, 1 Mar 2018 00:34:25 +0000 (01:34 +0100)
src/librustc_lint/types.rs
src/test/ui/lint/type-overflow.stderr

index db9dfedc656ba23d12d80c67163d1a3d0f6ae6e6..02aef271c37db2d916830fb4d7f762c021923ea1 100644 (file)
@@ -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<String> {
         //  - `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 @@ 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();
         }
     }
 }
index 425f76da5cb4ed594a805c84fbac79b38b62ed27..89718c7696a8dda4eb35035467d73dfcdf2b7081 100644 (file)
@@ -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`