From badb81a6129b84a9f01223ab73a56ffe52bf33ce Mon Sep 17 00:00:00 2001 From: George Bateman Date: Tue, 25 Jan 2022 23:19:00 +0000 Subject: [PATCH] #91939: integer to char cast error, make more targeted --- compiler/rustc_typeck/src/check/cast.rs | 21 ++++++++++++++----- .../const-eval/const-eval-overflow-4b.stderr | 6 ++++++ src/test/ui/error-codes/E0604.stderr | 6 ++++++ src/test/ui/error-festival.stderr | 6 ++++++ .../ui/mismatched_types/cast-rfc0401.stderr | 6 ++++++ 5 files changed, 40 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_typeck/src/check/cast.rs b/compiler/rustc_typeck/src/check/cast.rs index f6b5e0084d1..be0b7733579 100644 --- a/compiler/rustc_typeck/src/check/cast.rs +++ b/compiler/rustc_typeck/src/check/cast.rs @@ -328,17 +328,28 @@ impl<'a, 'tcx> CastCheck<'tcx> { err.emit(); } CastError::CastToChar => { - type_error_struct!( + let mut err = type_error_struct!( fcx.tcx.sess, self.span, self.expr_ty, E0604, "only `u8` can be cast as `char`, not `{}`", self.expr_ty - ) - .span_label(self.span, "invalid cast") - .span_help(self.span, "try `char::from_u32` instead") - .emit(); + ); + err.span_label(self.span, "invalid cast"); + if self.expr_ty.is_numeric() { + err.span_help( + self.span, + if self.expr_ty == fcx.tcx.types.i8 { + "try casting from `u8` instead" + } else if self.expr_ty == fcx.tcx.types.u32 { + "try `char::from_u32` instead" + } else { + "try `char::from_u32` instead (via a `u32`)" + }, + ); + } + err.emit(); } CastError::NonScalar => { let mut err = type_error_struct!( diff --git a/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr b/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr index 1e181c465db..f59ff329d18 100644 --- a/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr +++ b/src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr @@ -17,6 +17,12 @@ error[E0604]: only `u8` can be cast as `char`, not `i8` | LL | : [u32; 5i8 as char as usize] | ^^^^^^^^^^^ invalid cast + | +help: try casting from `u8` instead + --> $DIR/const-eval-overflow-4b.rs:22:13 + | +LL | : [u32; 5i8 as char as usize] + | ^^^^^^^^^^^ error: aborting due to 3 previous errors diff --git a/src/test/ui/error-codes/E0604.stderr b/src/test/ui/error-codes/E0604.stderr index 18835310bd5..d715d28b73c 100644 --- a/src/test/ui/error-codes/E0604.stderr +++ b/src/test/ui/error-codes/E0604.stderr @@ -3,6 +3,12 @@ error[E0604]: only `u8` can be cast as `char`, not `u32` | LL | 1u32 as char; | ^^^^^^^^^^^^ invalid cast + | +help: try `char::from_u32` instead + --> $DIR/E0604.rs:2:5 + | +LL | 1u32 as char; + | ^^^^^^^^^^^^ error: aborting due to previous error diff --git a/src/test/ui/error-festival.stderr b/src/test/ui/error-festival.stderr index b8cd7b7464a..0ddb6fc99b0 100644 --- a/src/test/ui/error-festival.stderr +++ b/src/test/ui/error-festival.stderr @@ -58,6 +58,12 @@ error[E0604]: only `u8` can be cast as `char`, not `u32` | LL | 0u32 as char; | ^^^^^^^^^^^^ invalid cast + | +help: try `char::from_u32` instead + --> $DIR/error-festival.rs:25:5 + | +LL | 0u32 as char; + | ^^^^^^^^^^^^ error[E0605]: non-primitive cast: `u8` as `Vec` --> $DIR/error-festival.rs:29:5 diff --git a/src/test/ui/mismatched_types/cast-rfc0401.stderr b/src/test/ui/mismatched_types/cast-rfc0401.stderr index 7f91d5ed42c..6dbf24baf23 100644 --- a/src/test/ui/mismatched_types/cast-rfc0401.stderr +++ b/src/test/ui/mismatched_types/cast-rfc0401.stderr @@ -99,6 +99,12 @@ error[E0604]: only `u8` can be cast as `char`, not `u32` | LL | let _ = 0x61u32 as char; | ^^^^^^^^^^^^^^^ invalid cast + | +help: try `char::from_u32` instead + --> $DIR/cast-rfc0401.rs:41:13 + | +LL | let _ = 0x61u32 as char; + | ^^^^^^^^^^^^^^^ error[E0606]: casting `bool` as `f32` is invalid --> $DIR/cast-rfc0401.rs:43:13