Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add source type for invalid bool casts #115765

Merged
merged 1 commit into from
Sep 12, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 7 additions & 2 deletions compiler/rustc_hir_typeck/src/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -321,8 +321,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`");
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) {
Expand Down
40 changes: 38 additions & 2 deletions tests/ui/cast/cast-as-bool.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,48 @@
fn main() {
let u = 5 as bool; //~ ERROR cannot cast as `bool`
let u = 5 as bool; //~ ERROR cannot cast `i32` as `bool`
//~| HELP compare with zero instead
//~| SUGGESTION 5 != 0

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

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

let _ = 64.0_f64 as bool; //~ ERROR cannot cast `f64` as `bool`
//~| HELP compare with zero instead

// Enums that can normally be cast to integers can't be cast to `bool`, just like integers.
// Note that enums that cannot be cast to integers can't be cast to anything at *all*
// so that's not tested here.
enum IntEnum {
Zero,
One,
Two
}
let _ = IntEnum::One as bool; //~ ERROR cannot cast `IntEnum` as `bool`

fn uwu(_: u8) -> String {
todo!()
}

unsafe fn owo() {}

// fn item to bool
let _ = uwu as bool; //~ ERROR cannot cast `fn(u8) -> String {uwu}` as `bool`
// unsafe fn item
let _ = owo as bool; //~ ERROR cannot cast `unsafe fn() {owo}` as `bool`

// fn ptr to bool
let _ = uwu as fn(u8) -> String as bool; //~ ERROR cannot cast `fn(u8) -> String` as `bool`

let _ = 'x' as bool; //~ ERROR cannot cast `char` as `bool`

let ptr = 1 as *const ();

let _ = ptr as bool; //~ ERROR cannot cast `*const ()` as `bool`

let v = "hello" as bool;
//~^ ERROR casting `&'static str` as `bool` is invalid
//~| HELP consider using the `is_empty` method on `&'static str` to determine if it contains anything
Expand Down
56 changes: 52 additions & 4 deletions tests/ui/cast/cast-as-bool.stderr
Original file line number Diff line number Diff line change
@@ -1,18 +1,66 @@
error[E0054]: cannot cast as `bool`
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`

error[E0054]: cannot cast as `bool`
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`

error[E0606]: casting `&'static str` as `bool` is invalid
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`

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`

error[E0054]: cannot cast `IntEnum` as `bool`
--> $DIR/cast-as-bool.rs:24:13
|
LL | let _ = IntEnum::One as bool;
| ^^^^^^^^^^^^^^^^^^^^ unsupported cast

error[E0054]: cannot cast `fn(u8) -> String {uwu}` as `bool`
--> $DIR/cast-as-bool.rs:33:13
|
LL | let _ = uwu as bool;
| ^^^^^^^^^^^ unsupported cast

error[E0054]: cannot cast `unsafe fn() {owo}` as `bool`
--> $DIR/cast-as-bool.rs:35:13
|
LL | let _ = owo as bool;
| ^^^^^^^^^^^ unsupported cast

error[E0054]: cannot cast `fn(u8) -> String` as `bool`
--> $DIR/cast-as-bool.rs:38:13
|
LL | let _ = uwu as fn(u8) -> String as bool;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ unsupported cast

error[E0054]: cannot cast `char` as `bool`
--> $DIR/cast-as-bool.rs:40:13
|
LL | let _ = 'x' as bool;
| ^^^^^^^^^^^ unsupported cast

error[E0054]: cannot cast `*const ()` as `bool`
--> $DIR/cast-as-bool.rs:44:13
|
LL | let _ = ptr as bool;
| ^^^^^^^^^^^ unsupported cast

error[E0606]: casting `&'static str` as `bool` is invalid
--> $DIR/cast-as-bool.rs:46:13
|
LL | let v = "hello" as bool;
| ^^^^^^^^^^^^^^^
|
Expand All @@ -21,7 +69,7 @@ help: consider using the `is_empty` method on `&'static str` to determine if it
LL | let v = !"hello".is_empty();
| + ~~~~~~~~~~~

error: aborting due to 3 previous errors
error: aborting due to 11 previous errors

Some errors have detailed explanations: E0054, E0606.
For more information about an error, try `rustc --explain E0054`.
2 changes: 1 addition & 1 deletion tests/ui/cast/cast-rfc0401-2.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

fn main() {
let _ = 3 as bool;
//~^ ERROR cannot cast as `bool`
//~^ ERROR cannot cast `i32` as `bool`
}
2 changes: 1 addition & 1 deletion tests/ui/cast/cast-rfc0401-2.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0054]: cannot cast as `bool`
error[E0054]: cannot cast `i32` as `bool`
--> $DIR/cast-rfc0401-2.rs:6:13
|
LL | let _ = 3 as bool;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-codes/E0054.stderr
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
error[E0054]: cannot cast as `bool`
error[E0054]: cannot cast `i32` as `bool`
--> $DIR/E0054.rs:3:24
|
LL | let x_is_nonzero = x as bool;
Expand Down
2 changes: 1 addition & 1 deletion tests/ui/error-festival.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ error[E0605]: non-primitive cast: `u8` as `Vec<u8>`
LL | x as Vec<u8>;
| ^^^^^^^^^^^^ an `as` expression can only be used to convert between primitive types or to coerce to a specific trait object

error[E0054]: cannot cast as `bool`
error[E0054]: cannot cast `{integer}` as `bool`
--> $DIR/error-festival.rs:33:24
|
LL | let x_is_nonzero = x as bool;
Expand Down
4 changes: 2 additions & 2 deletions tests/ui/mismatched_types/cast-rfc0401.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -82,13 +82,13 @@ error[E0606]: casting `f32` as `*const u8` is invalid
LL | let _ = f as *const u8;
| ^^^^^^^^^^^^^^

error[E0054]: cannot cast as `bool`
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`

error[E0054]: cannot cast as `bool`
error[E0054]: cannot cast `E` as `bool`
--> $DIR/cast-rfc0401.rs:40:13
|
LL | let _ = E::A as bool;
Expand Down
Loading