about summary refs log tree commit diff
diff options
context:
space:
mode:
authorclubby789 <jamie@hill-daniel.co.uk>2023-09-15 15:54:47 +0000
committerclubby789 <jamie@hill-daniel.co.uk>2023-09-18 14:03:57 +0000
commitc2841e2a1eb2712d580ef83cb7986151ece8c516 (patch)
treecb3059443fb78785f0a614edd7dd2605c40607cd
parentdcb3e70861f2958c3925e8398bd3e41a88114398 (diff)
downloadrust-c2841e2a1eb2712d580ef83cb7986151ece8c516.tar.gz
rust-c2841e2a1eb2712d580ef83cb7986151ece8c516.zip
Migrate 'cast to bool' diagnostic
-rw-r--r--compiler/rustc_hir_typeck/messages.ftl5
-rw-r--r--compiler/rustc_hir_typeck/src/cast.rs32
-rw-r--r--compiler/rustc_hir_typeck/src/errors.rs23
-rw-r--r--tests/ui/cast/cast-as-bool.rs4
-rw-r--r--tests/ui/cast/cast-as-bool.stderr28
-rw-r--r--tests/ui/cast/cast-rfc0401-2.stderr7
-rw-r--r--tests/ui/error-codes/E0054.stderr7
-rw-r--r--tests/ui/error-festival.stderr7
-rw-r--r--tests/ui/mismatched_types/cast-rfc0401.stderr7
9 files changed, 84 insertions, 36 deletions
diff --git a/compiler/rustc_hir_typeck/messages.ftl b/compiler/rustc_hir_typeck/messages.ftl
index fb03b93b249..b1074745d72 100644
--- a/compiler/rustc_hir_typeck/messages.ftl
+++ b/compiler/rustc_hir_typeck/messages.ftl
@@ -16,6 +16,11 @@ hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`
     *[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it
 }
 
+hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool`
+    .suggestion = compare with zero instead
+    .help = compare with zero instead
+    .label = unsupported cast
+
 hir_typeck_const_select_must_be_const = this argument must be a `const fn`
     .help = consult the documentation on `const_eval_select` for more information
 
diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs
index 9835951f948..bb1b7f2534f 100644
--- a/compiler/rustc_hir_typeck/src/cast.rs
+++ b/compiler/rustc_hir_typeck/src/cast.rs
@@ -322,33 +322,13 @@ impl<'a, 'tcx> CastCheck<'tcx> {
                 .emit();
             }
             CastError::CastToBool => {
-                let mut err = struct_span_err!(
-                    fcx.tcx.sess,
-                    self.span,
-                    E0054,
-                    "cannot cast `{}` as `bool`",
-                    self.expr_ty
-                );
-
-                if self.expr_ty.is_numeric() {
-                    match fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) {
-                        Ok(snippet) => {
-                            err.span_suggestion(
-                                self.span,
-                                "compare with zero instead",
-                                format!("{snippet} != 0"),
-                                Applicability::MachineApplicable,
-                            );
-                        }
-                        Err(_) => {
-                            err.span_help(self.span, "compare with zero instead");
-                        }
-                    }
+                let expr_ty = fcx.resolve_vars_if_possible(self.expr_ty);
+                let help = if self.expr_ty.is_numeric() {
+                    errors::CannotCastToBoolHelp::Numeric(self.expr_span.shrink_to_hi().with_hi(self.span.hi()))
                 } else {
-                    err.span_label(self.span, "unsupported cast");
-                }
-
-                err.emit();
+                    errors::CannotCastToBoolHelp::Unsupported(self.span)
+                };
+                fcx.tcx.sess.emit_err(errors::CannotCastToBool { span: self.span, expr_ty, help });
             }
             CastError::CastToChar => {
                 let mut err = type_error_struct!(
diff --git a/compiler/rustc_hir_typeck/src/errors.rs b/compiler/rustc_hir_typeck/src/errors.rs
index 11b555ba095..3bfe5a22df6 100644
--- a/compiler/rustc_hir_typeck/src/errors.rs
+++ b/compiler/rustc_hir_typeck/src/errors.rs
@@ -542,6 +542,29 @@ pub struct CandidateTraitNote {
 }
 
 #[derive(Diagnostic)]
+#[diag(hir_typeck_cannot_cast_to_bool, code = "E0054")]
+pub struct CannotCastToBool<'tcx> {
+    #[primary_span]
+    pub span: Span,
+    pub expr_ty: Ty<'tcx>,
+    #[subdiagnostic]
+    pub help: CannotCastToBoolHelp,
+}
+
+#[derive(Subdiagnostic)]
+pub enum CannotCastToBoolHelp {
+    #[suggestion(
+        hir_typeck_suggestion,
+        applicability = "machine-applicable",
+        code = " != 0",
+        style = "verbose"
+    )]
+    Numeric(#[primary_span] Span),
+    #[label(hir_typeck_label)]
+    Unsupported(#[primary_span] Span),
+}
+
+#[derive(Diagnostic)]
 #[diag(hir_typeck_ctor_is_private, code = "E0603")]
 pub struct CtorIsPrivate {
     #[primary_span]
diff --git a/tests/ui/cast/cast-as-bool.rs b/tests/ui/cast/cast-as-bool.rs
index 750a88f97eb..511a02718fe 100644
--- a/tests/ui/cast/cast-as-bool.rs
+++ b/tests/ui/cast/cast-as-bool.rs
@@ -1,11 +1,11 @@
 fn main() {
     let u = 5 as bool; //~ ERROR cannot cast `i32` as `bool`
                        //~| HELP compare with zero instead
-                       //~| SUGGESTION 5 != 0
+                       //~| SUGGESTION != 0
 
     let t = (1 + 2) as bool; //~ ERROR cannot cast `i32` as `bool`
                              //~| HELP compare with zero instead
-                             //~| SUGGESTION (1 + 2) != 0
+                             //~| SUGGESTION != 0
 
     let _ = 5_u32 as bool; //~ ERROR cannot cast `u32` as `bool`
                            //~| HELP compare with zero instead
diff --git a/tests/ui/cast/cast-as-bool.stderr b/tests/ui/cast/cast-as-bool.stderr
index 852fb30cc20..4ff56a95e49 100644
--- a/tests/ui/cast/cast-as-bool.stderr
+++ b/tests/ui/cast/cast-as-bool.stderr
@@ -2,25 +2,45 @@ error[E0054]: cannot cast `i32` as `bool`
   --> $DIR/cast-as-bool.rs:2:13
    |
 LL |     let u = 5 as bool;
-   |             ^^^^^^^^^ help: compare with zero instead: `5 != 0`
+   |             ^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let u = 5 != 0;
+   |               ~~~~
 
 error[E0054]: cannot cast `i32` as `bool`
   --> $DIR/cast-as-bool.rs:6:13
    |
 LL |     let t = (1 + 2) as bool;
-   |             ^^^^^^^^^^^^^^^ help: compare with zero instead: `(1 + 2) != 0`
+   |             ^^^^^^^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let t = (1 + 2) != 0;
+   |                     ~~~~
 
 error[E0054]: cannot cast `u32` as `bool`
   --> $DIR/cast-as-bool.rs:10:13
    |
 LL |     let _ = 5_u32 as bool;
-   |             ^^^^^^^^^^^^^ help: compare with zero instead: `5_u32 != 0`
+   |             ^^^^^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let _ = 5_u32 != 0;
+   |                   ~~~~
 
 error[E0054]: cannot cast `f64` as `bool`
   --> $DIR/cast-as-bool.rs:13:13
    |
 LL |     let _ = 64.0_f64 as bool;
-   |             ^^^^^^^^^^^^^^^^ help: compare with zero instead: `64.0_f64 != 0`
+   |             ^^^^^^^^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let _ = 64.0_f64 != 0;
+   |                      ~~~~
 
 error[E0054]: cannot cast `IntEnum` as `bool`
   --> $DIR/cast-as-bool.rs:24:13
diff --git a/tests/ui/cast/cast-rfc0401-2.stderr b/tests/ui/cast/cast-rfc0401-2.stderr
index 5dc21ca847c..dd90c3a9723 100644
--- a/tests/ui/cast/cast-rfc0401-2.stderr
+++ b/tests/ui/cast/cast-rfc0401-2.stderr
@@ -2,7 +2,12 @@ error[E0054]: cannot cast `i32` as `bool`
   --> $DIR/cast-rfc0401-2.rs:6:13
    |
 LL |     let _ = 3 as bool;
-   |             ^^^^^^^^^ help: compare with zero instead: `3 != 0`
+   |             ^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let _ = 3 != 0;
+   |               ~~~~
 
 error: aborting due to previous error
 
diff --git a/tests/ui/error-codes/E0054.stderr b/tests/ui/error-codes/E0054.stderr
index ea81f4476a7..0a4adabbaf6 100644
--- a/tests/ui/error-codes/E0054.stderr
+++ b/tests/ui/error-codes/E0054.stderr
@@ -2,7 +2,12 @@ error[E0054]: cannot cast `i32` as `bool`
   --> $DIR/E0054.rs:3:24
    |
 LL |     let x_is_nonzero = x as bool;
-   |                        ^^^^^^^^^ help: compare with zero instead: `x != 0`
+   |                        ^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let x_is_nonzero = x != 0;
+   |                          ~~~~
 
 error: aborting due to previous error
 
diff --git a/tests/ui/error-festival.stderr b/tests/ui/error-festival.stderr
index 74a2bc8d768..9d75671c4e6 100644
--- a/tests/ui/error-festival.stderr
+++ b/tests/ui/error-festival.stderr
@@ -63,7 +63,12 @@ error[E0054]: cannot cast `{integer}` as `bool`
   --> $DIR/error-festival.rs:33:24
    |
 LL |     let x_is_nonzero = x as bool;
-   |                        ^^^^^^^^^ help: compare with zero instead: `x != 0`
+   |                        ^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let x_is_nonzero = x != 0;
+   |                          ~~~~
 
 error[E0606]: casting `&u8` as `u32` is invalid
   --> $DIR/error-festival.rs:37:18
diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr
index 0cea60746bf..d63cec48917 100644
--- a/tests/ui/mismatched_types/cast-rfc0401.stderr
+++ b/tests/ui/mismatched_types/cast-rfc0401.stderr
@@ -86,7 +86,12 @@ error[E0054]: cannot cast `i32` as `bool`
   --> $DIR/cast-rfc0401.rs:39:13
    |
 LL |     let _ = 3_i32 as bool;
-   |             ^^^^^^^^^^^^^ help: compare with zero instead: `3_i32 != 0`
+   |             ^^^^^^^^^^^^^
+   |
+help: compare with zero instead
+   |
+LL |     let _ = 3_i32 != 0;
+   |                   ~~~~
 
 error[E0054]: cannot cast `E` as `bool`
   --> $DIR/cast-rfc0401.rs:40:13