From e36adff4c24c1cd61fcc72c94cf9d312ff366dc1 Mon Sep 17 00:00:00 2001 From: asquared31415 <34665709+asquared31415@users.noreply.github.com> Date: Mon, 11 Sep 2023 18:04:22 +0000 Subject: [PATCH] add source type for invalid bool casts --- compiler/rustc_hir_typeck/src/cast.rs | 9 ++- tests/ui/cast/cast-as-bool.rs | 40 ++++++++++++- tests/ui/cast/cast-as-bool.stderr | 56 +++++++++++++++++-- tests/ui/cast/cast-rfc0401-2.rs | 2 +- tests/ui/cast/cast-rfc0401-2.stderr | 2 +- tests/ui/error-codes/E0054.stderr | 2 +- tests/ui/error-festival.stderr | 2 +- tests/ui/mismatched_types/cast-rfc0401.stderr | 4 +- 8 files changed, 103 insertions(+), 14 deletions(-) diff --git a/compiler/rustc_hir_typeck/src/cast.rs b/compiler/rustc_hir_typeck/src/cast.rs index 31a03fabe4f20..e8d4e6b447f70 100644 --- a/compiler/rustc_hir_typeck/src/cast.rs +++ b/compiler/rustc_hir_typeck/src/cast.rs @@ -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) { diff --git a/tests/ui/cast/cast-as-bool.rs b/tests/ui/cast/cast-as-bool.rs index fbebc80d91ced..750a88f97ebed 100644 --- a/tests/ui/cast/cast-as-bool.rs +++ b/tests/ui/cast/cast-as-bool.rs @@ -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 diff --git a/tests/ui/cast/cast-as-bool.stderr b/tests/ui/cast/cast-as-bool.stderr index 19ac8f10fec21..852fb30cc202f 100644 --- a/tests/ui/cast/cast-as-bool.stderr +++ b/tests/ui/cast/cast-as-bool.stderr @@ -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; | ^^^^^^^^^^^^^^^ | @@ -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`. diff --git a/tests/ui/cast/cast-rfc0401-2.rs b/tests/ui/cast/cast-rfc0401-2.rs index 7709aa34104cc..70604a587ea1f 100644 --- a/tests/ui/cast/cast-rfc0401-2.rs +++ b/tests/ui/cast/cast-rfc0401-2.rs @@ -4,5 +4,5 @@ fn main() { let _ = 3 as bool; - //~^ ERROR cannot cast as `bool` + //~^ ERROR cannot cast `i32` as `bool` } diff --git a/tests/ui/cast/cast-rfc0401-2.stderr b/tests/ui/cast/cast-rfc0401-2.stderr index 52f6af78a9be5..5dc21ca847c93 100644 --- a/tests/ui/cast/cast-rfc0401-2.stderr +++ b/tests/ui/cast/cast-rfc0401-2.stderr @@ -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; diff --git a/tests/ui/error-codes/E0054.stderr b/tests/ui/error-codes/E0054.stderr index 6b1092760fb49..ea81f4476a7da 100644 --- a/tests/ui/error-codes/E0054.stderr +++ b/tests/ui/error-codes/E0054.stderr @@ -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; diff --git a/tests/ui/error-festival.stderr b/tests/ui/error-festival.stderr index e8ee1d96942f7..74a2bc8d7682e 100644 --- a/tests/ui/error-festival.stderr +++ b/tests/ui/error-festival.stderr @@ -59,7 +59,7 @@ error[E0605]: non-primitive cast: `u8` as `Vec` LL | x as Vec; | ^^^^^^^^^^^^ 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; diff --git a/tests/ui/mismatched_types/cast-rfc0401.stderr b/tests/ui/mismatched_types/cast-rfc0401.stderr index 6b9ac3c585236..0cea60746bfe3 100644 --- a/tests/ui/mismatched_types/cast-rfc0401.stderr +++ b/tests/ui/mismatched_types/cast-rfc0401.stderr @@ -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;