about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndy Russell <arussell123@gmail.com>2019-01-09 16:57:49 -0500
committerAndy Russell <arussell123@gmail.com>2019-01-09 16:59:12 -0500
commit565c39de439f59e83efe2f0064c0dbebb287c8e9 (patch)
treec35b6af967e03bd7b4f555d564fb8edc719b3ec5
parent6ecad338381cc3b8d56e2df22e5971a598eddd6c (diff)
downloadrust-565c39de439f59e83efe2f0064c0dbebb287c8e9.tar.gz
rust-565c39de439f59e83efe2f0064c0dbebb287c8e9.zip
provide suggestion for invalid boolean cast
Also, don't suggest comparing to zero for non-numeric expressions.
-rw-r--r--src/librustc_typeck/check/cast.rs26
-rw-r--r--src/test/ui/cast/cast-as-bool.rs9
-rw-r--r--src/test/ui/cast/cast-as-bool.stderr18
-rw-r--r--src/test/ui/cast/cast-rfc0401-2.stderr4
-rw-r--r--src/test/ui/error-codes/E0054.stderr4
-rw-r--r--src/test/ui/error-festival.stderr4
-rw-r--r--src/test/ui/mismatched_types/cast-rfc0401.stderr6
7 files changed, 47 insertions, 24 deletions
diff --git a/src/librustc_typeck/check/cast.rs b/src/librustc_typeck/check/cast.rs
index 38f9adee0a4..220d5676ab4 100644
--- a/src/librustc_typeck/check/cast.rs
+++ b/src/librustc_typeck/check/cast.rs
@@ -251,10 +251,28 @@ impl<'a, 'gcx, 'tcx> CastCheck<'tcx> {
                     .emit();
             }
             CastError::CastToBool => {
-                struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`")
-                    .span_label(self.span, "unsupported cast")
-                    .help("compare with zero instead")
-                    .emit();
+                let mut err =
+                    struct_span_err!(fcx.tcx.sess, self.span, E0054, "cannot cast as `bool`");
+
+                if self.expr_ty.is_numeric() {
+                    match fcx.tcx.sess.source_map().span_to_snippet(self.expr.span) {
+                        Ok(snippet) => {
+                            err.span_suggestion_with_applicability(
+                                self.span,
+                                "compare with zero instead",
+                                format!("{} != 0", snippet),
+                                Applicability::MachineApplicable,
+                            );
+                        }
+                        Err(_) => {
+                            err.span_help(self.span, "compare with zero instead");
+                        }
+                    }
+                } else {
+                    err.span_label(self.span, "unsupported cast");
+                }
+
+                err.emit();
             }
             CastError::CastToChar => {
                 type_error_struct!(fcx.tcx.sess, self.span, self.expr_ty, E0604,
diff --git a/src/test/ui/cast/cast-as-bool.rs b/src/test/ui/cast/cast-as-bool.rs
index 7a0bd0ec098..8130f4dedc9 100644
--- a/src/test/ui/cast/cast-as-bool.rs
+++ b/src/test/ui/cast/cast-as-bool.rs
@@ -1,4 +1,9 @@
 fn main() {
-    let u = 5 as bool;
-    //~^ ERROR cannot cast as `bool`
+    let u = 5 as bool; //~ ERROR cannot cast as `bool`
+                       //~| HELP compare with zero instead
+                       //~| SUGGESTION 5 != 0
+    let t = (1 + 2) as bool; //~ ERROR cannot cast as `bool`
+                             //~| HELP compare with zero instead
+                             //~| SUGGESTION (1 + 2) != 0
+    let v = "hello" as bool; //~ ERROR cannot cast as `bool`
 }
diff --git a/src/test/ui/cast/cast-as-bool.stderr b/src/test/ui/cast/cast-as-bool.stderr
index 086d08a569a..6099a4195b3 100644
--- a/src/test/ui/cast/cast-as-bool.stderr
+++ b/src/test/ui/cast/cast-as-bool.stderr
@@ -1,11 +1,21 @@
 error[E0054]: cannot cast as `bool`
   --> $DIR/cast-as-bool.rs:2:13
    |
-LL |     let u = 5 as bool;
-   |             ^^^^^^^^^ unsupported cast
+LL |     let u = 5 as bool; //~ ERROR cannot cast as `bool`
+   |             ^^^^^^^^^ help: compare with zero instead: `5 != 0`
+
+error[E0054]: cannot cast as `bool`
+  --> $DIR/cast-as-bool.rs:5:13
+   |
+LL |     let t = (1 + 2) as bool; //~ ERROR cannot cast as `bool`
+   |             ^^^^^^^^^^^^^^^ help: compare with zero instead: `(1 + 2) != 0`
+
+error[E0054]: cannot cast as `bool`
+  --> $DIR/cast-as-bool.rs:8:13
    |
-   = help: compare with zero instead
+LL |     let v = "hello" as bool; //~ ERROR cannot cast as `bool`
+   |             ^^^^^^^^^^^^^^^ unsupported cast
 
-error: aborting due to previous error
+error: aborting due to 3 previous errors
 
 For more information about this error, try `rustc --explain E0054`.
diff --git a/src/test/ui/cast/cast-rfc0401-2.stderr b/src/test/ui/cast/cast-rfc0401-2.stderr
index 3bf6e5367f0..52f6af78a9b 100644
--- a/src/test/ui/cast/cast-rfc0401-2.stderr
+++ b/src/test/ui/cast/cast-rfc0401-2.stderr
@@ -2,9 +2,7 @@ error[E0054]: cannot cast as `bool`
   --> $DIR/cast-rfc0401-2.rs:6:13
    |
 LL |     let _ = 3 as bool;
-   |             ^^^^^^^^^ unsupported cast
-   |
-   = help: compare with zero instead
+   |             ^^^^^^^^^ help: compare with zero instead: `3 != 0`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-codes/E0054.stderr b/src/test/ui/error-codes/E0054.stderr
index 416029c5f86..cce32fa2944 100644
--- a/src/test/ui/error-codes/E0054.stderr
+++ b/src/test/ui/error-codes/E0054.stderr
@@ -2,9 +2,7 @@ error[E0054]: cannot cast as `bool`
   --> $DIR/E0054.rs:3:24
    |
 LL |     let x_is_nonzero = x as bool; //~ ERROR E0054
-   |                        ^^^^^^^^^ unsupported cast
-   |
-   = help: compare with zero instead
+   |                        ^^^^^^^^^ help: compare with zero instead: `x != 0`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr
index 2a482722169..006ab434f35 100644
--- a/src/test/ui/error-festival.stderr
+++ b/src/test/ui/error-festival.stderr
@@ -52,9 +52,7 @@ error[E0054]: cannot cast as `bool`
   --> $DIR/error-festival.rs:33:24
    |
 LL |     let x_is_nonzero = x as bool;
-   |                        ^^^^^^^^^ unsupported cast
-   |
-   = help: compare with zero instead
+   |                        ^^^^^^^^^ help: compare with zero instead: `x != 0`
 
 error[E0606]: casting `&u8` as `u32` is invalid
   --> $DIR/error-festival.rs:37:18
diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr
index 158d1146169..10b19ff836f 100644
--- a/src/test/ui/mismatched_types/cast-rfc0401.stderr
+++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr
@@ -90,17 +90,13 @@ error[E0054]: cannot cast as `bool`
   --> $DIR/cast-rfc0401.rs:39:13
    |
 LL |     let _ = 3_i32 as bool; //~ ERROR cannot cast
-   |             ^^^^^^^^^^^^^ unsupported cast
-   |
-   = help: compare with zero instead
+   |             ^^^^^^^^^^^^^ help: compare with zero instead: `3_i32 != 0`
 
 error[E0054]: cannot cast as `bool`
   --> $DIR/cast-rfc0401.rs:40:13
    |
 LL |     let _ = E::A as bool; //~ ERROR cannot cast
    |             ^^^^^^^^^^^^ unsupported cast
-   |
-   = help: compare with zero instead
 
 error[E0604]: only `u8` can be cast as `char`, not `u32`
   --> $DIR/cast-rfc0401.rs:41:13