Skip to content

Commit d5c1d48

Browse files
committed
Migrate 'cast to bool' diagnostic
1 parent 38209ff commit d5c1d48

File tree

9 files changed

+87
-36
lines changed

9 files changed

+87
-36
lines changed

compiler/rustc_hir_typeck/messages.ftl

+5
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ hir_typeck_candidate_trait_note = `{$trait_name}` defines an item `{$item_name}`
1616
*[other] , perhaps you need to restrict type parameter `{$action_or_ty}` with it
1717
}
1818
19+
hir_typeck_cannot_cast_to_bool = cannot cast `{$expr_ty}` as `bool`
20+
.suggestion = compare with zero instead
21+
.help = compare with zero instead
22+
.label = unsupported cast
23+
1924
hir_typeck_const_select_must_be_const = this argument must be a `const fn`
2025
.help = consult the documentation on `const_eval_select` for more information
2126

compiler/rustc_hir_typeck/src/cast.rs

+9-26
Original file line numberDiff line numberDiff line change
@@ -322,33 +322,16 @@ impl<'a, 'tcx> CastCheck<'tcx> {
322322
.emit();
323323
}
324324
CastError::CastToBool => {
325-
let mut err = struct_span_err!(
326-
fcx.tcx.sess,
327-
self.span,
328-
E0054,
329-
"cannot cast `{}` as `bool`",
330-
self.expr_ty
331-
);
332-
333-
if self.expr_ty.is_numeric() {
334-
match fcx.tcx.sess.source_map().span_to_snippet(self.expr_span) {
335-
Ok(snippet) => {
336-
err.span_suggestion(
337-
self.span,
338-
"compare with zero instead",
339-
format!("{snippet} != 0"),
340-
Applicability::MachineApplicable,
341-
);
342-
}
343-
Err(_) => {
344-
err.span_help(self.span, "compare with zero instead");
345-
}
346-
}
325+
let help = if self.expr_ty.is_numeric() {
326+
errors::CannotCastToBoolHelp::Numeric(self.expr_span.shrink_to_hi().with_hi(self.span.hi()))
347327
} else {
348-
err.span_label(self.span, "unsupported cast");
349-
}
350-
351-
err.emit();
328+
errors::CannotCastToBoolHelp::Unsupported(self.span)
329+
};
330+
fcx.tcx.sess.emit_err(errors::CannotCastToBool {
331+
span: self.span,
332+
expr_ty: self.expr_ty,
333+
help,
334+
});
352335
}
353336
CastError::CastToChar => {
354337
let mut err = type_error_struct!(

compiler/rustc_hir_typeck/src/errors.rs

+23
Original file line numberDiff line numberDiff line change
@@ -495,6 +495,29 @@ pub struct CandidateTraitNote {
495495
pub action_or_ty: String,
496496
}
497497

498+
#[derive(Diagnostic)]
499+
#[diag(hir_typeck_cannot_cast_to_bool, code = "E0054")]
500+
pub struct CannotCastToBool<'tcx> {
501+
#[primary_span]
502+
pub span: Span,
503+
pub expr_ty: Ty<'tcx>,
504+
#[subdiagnostic]
505+
pub help: CannotCastToBoolHelp,
506+
}
507+
508+
#[derive(Subdiagnostic)]
509+
pub enum CannotCastToBoolHelp {
510+
#[suggestion(
511+
hir_typeck_suggestion,
512+
applicability = "machine-applicable",
513+
code = " != 0",
514+
style = "verbose"
515+
)]
516+
Numeric(#[primary_span] Span),
517+
#[label(hir_typeck_label)]
518+
Unsupported(#[primary_span] Span),
519+
}
520+
498521
#[derive(Diagnostic)]
499522
#[diag(hir_typeck_ctor_is_private, code = "E0603")]
500523
pub struct CtorIsPrivate {

tests/ui/cast/cast-as-bool.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
fn main() {
22
let u = 5 as bool; //~ ERROR cannot cast `i32` as `bool`
33
//~| HELP compare with zero instead
4-
//~| SUGGESTION 5 != 0
4+
//~| SUGGESTION != 0
55

66
let t = (1 + 2) as bool; //~ ERROR cannot cast `i32` as `bool`
77
//~| HELP compare with zero instead
8-
//~| SUGGESTION (1 + 2) != 0
8+
//~| SUGGESTION != 0
99

1010
let _ = 5_u32 as bool; //~ ERROR cannot cast `u32` as `bool`
1111
//~| HELP compare with zero instead

tests/ui/cast/cast-as-bool.stderr

+24-4
Original file line numberDiff line numberDiff line change
@@ -2,25 +2,45 @@ error[E0054]: cannot cast `i32` as `bool`
22
--> $DIR/cast-as-bool.rs:2:13
33
|
44
LL | let u = 5 as bool;
5-
| ^^^^^^^^^ help: compare with zero instead: `5 != 0`
5+
| ^^^^^^^^^
6+
|
7+
help: compare with zero instead
8+
|
9+
LL | let u = 5 != 0;
10+
| ~~~~
611

712
error[E0054]: cannot cast `i32` as `bool`
813
--> $DIR/cast-as-bool.rs:6:13
914
|
1015
LL | let t = (1 + 2) as bool;
11-
| ^^^^^^^^^^^^^^^ help: compare with zero instead: `(1 + 2) != 0`
16+
| ^^^^^^^^^^^^^^^
17+
|
18+
help: compare with zero instead
19+
|
20+
LL | let t = (1 + 2) != 0;
21+
| ~~~~
1222

1323
error[E0054]: cannot cast `u32` as `bool`
1424
--> $DIR/cast-as-bool.rs:10:13
1525
|
1626
LL | let _ = 5_u32 as bool;
17-
| ^^^^^^^^^^^^^ help: compare with zero instead: `5_u32 != 0`
27+
| ^^^^^^^^^^^^^
28+
|
29+
help: compare with zero instead
30+
|
31+
LL | let _ = 5_u32 != 0;
32+
| ~~~~
1833

1934
error[E0054]: cannot cast `f64` as `bool`
2035
--> $DIR/cast-as-bool.rs:13:13
2136
|
2237
LL | let _ = 64.0_f64 as bool;
23-
| ^^^^^^^^^^^^^^^^ help: compare with zero instead: `64.0_f64 != 0`
38+
| ^^^^^^^^^^^^^^^^
39+
|
40+
help: compare with zero instead
41+
|
42+
LL | let _ = 64.0_f64 != 0;
43+
| ~~~~
2444

2545
error[E0054]: cannot cast `IntEnum` as `bool`
2646
--> $DIR/cast-as-bool.rs:24:13

tests/ui/cast/cast-rfc0401-2.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0054]: cannot cast `i32` as `bool`
22
--> $DIR/cast-rfc0401-2.rs:6:13
33
|
44
LL | let _ = 3 as bool;
5-
| ^^^^^^^^^ help: compare with zero instead: `3 != 0`
5+
| ^^^^^^^^^
6+
|
7+
help: compare with zero instead
8+
|
9+
LL | let _ = 3 != 0;
10+
| ~~~~
611

712
error: aborting due to previous error
813

tests/ui/error-codes/E0054.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,12 @@ error[E0054]: cannot cast `i32` as `bool`
22
--> $DIR/E0054.rs:3:24
33
|
44
LL | let x_is_nonzero = x as bool;
5-
| ^^^^^^^^^ help: compare with zero instead: `x != 0`
5+
| ^^^^^^^^^
6+
|
7+
help: compare with zero instead
8+
|
9+
LL | let x_is_nonzero = x != 0;
10+
| ~~~~
611

712
error: aborting due to previous error
813

tests/ui/error-festival.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,12 @@ error[E0054]: cannot cast `{integer}` as `bool`
6363
--> $DIR/error-festival.rs:33:24
6464
|
6565
LL | let x_is_nonzero = x as bool;
66-
| ^^^^^^^^^ help: compare with zero instead: `x != 0`
66+
| ^^^^^^^^^
67+
|
68+
help: compare with zero instead
69+
|
70+
LL | let x_is_nonzero = x != 0;
71+
| ~~~~
6772

6873
error[E0606]: casting `&u8` as `u32` is invalid
6974
--> $DIR/error-festival.rs:37:18

tests/ui/mismatched_types/cast-rfc0401.stderr

+6-1
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,12 @@ error[E0054]: cannot cast `i32` as `bool`
8686
--> $DIR/cast-rfc0401.rs:39:13
8787
|
8888
LL | let _ = 3_i32 as bool;
89-
| ^^^^^^^^^^^^^ help: compare with zero instead: `3_i32 != 0`
89+
| ^^^^^^^^^^^^^
90+
|
91+
help: compare with zero instead
92+
|
93+
LL | let _ = 3_i32 != 0;
94+
| ~~~~
9095

9196
error[E0054]: cannot cast `E` as `bool`
9297
--> $DIR/cast-rfc0401.rs:40:13

0 commit comments

Comments
 (0)