diff --git a/gcc/rust/typecheck/rust-casts.cc b/gcc/rust/typecheck/rust-casts.cc index 75b2872104fd..7439debb916c 100644 --- a/gcc/rust/typecheck/rust-casts.cc +++ b/gcc/rust/typecheck/rust-casts.cc @@ -300,11 +300,33 @@ TypeCastRules::check_ptr_ptr_cast () void TypeCastRules::emit_cast_error () const { - // error[E0604] rich_location r (line_table, locus); r.add_range (from.get_locus ()); r.add_range (to.get_locus ()); - rust_error_at (r, ErrorCode::E0054, "invalid cast %<%s%> to %<%s%>", + ErrorCode error_code; + std::string error_msg; + switch (to.get_ty ()->get_kind ()) + { + case TyTy::TypeKind::BOOL: + error_msg = "cannot cast %qs as %qs"; + error_code = ErrorCode::E0054; + break; + case TyTy::TypeKind::CHAR: + error_msg + += "cannot cast %qs as %qs, only % can be cast as %"; + error_code = ErrorCode::E0604; + break; + case TyTy::TypeKind::SLICE: + error_msg = "cast to unsized type: %qs as %qs"; + error_code = ErrorCode::E0620; + break; + + default: + error_msg = "casting %qs as %qs is invalid"; + error_code = ErrorCode::E0606; + break; + } + rust_error_at (r, error_code, error_msg.c_str (), from.get_ty ()->get_name ().c_str (), to.get_ty ()->get_name ().c_str ()); } diff --git a/gcc/testsuite/rust/compile/all-cast.rs b/gcc/testsuite/rust/compile/all-cast.rs new file mode 100644 index 000000000000..fa24373a6779 --- /dev/null +++ b/gcc/testsuite/rust/compile/all-cast.rs @@ -0,0 +1,11 @@ +fn main() { + let x = 5; + let x_is_nonzero = x as bool; // { dg-error "cannot cast .. as .bool." } + + 0u32 as char; // { dg-error "cannot cast .u32. as .char., only .u8. can be cast as .char." } + + let x = &[1_usize, 2] as [usize]; // { dg-error "cast to unsized type: .& .usize:CAPACITY.. as ..usize.." } + + let a = &0u8; // Here, `x` is a `&u8`. + let y: u32 = a as u32; // { dg-error "casting .& u8. as .u32. is invalid" } +} diff --git a/gcc/testsuite/rust/compile/bad_as_bool_char.rs b/gcc/testsuite/rust/compile/bad_as_bool_char.rs index 9652915fe117..1828d2256f29 100644 --- a/gcc/testsuite/rust/compile/bad_as_bool_char.rs +++ b/gcc/testsuite/rust/compile/bad_as_bool_char.rs @@ -2,17 +2,17 @@ pub fn main () { let t = true; let f = false; - let fone = t as f32; // { dg-error "invalid cast" } - let fzero = f as f64; // { dg-error "invalid cast" } + let fone = t as f32; // { dg-error "casting .bool. as .f32. is invalid" } + let fzero = f as f64; // { dg-error "casting .bool. as .f64. is invalid" } - let nb = 0u8 as bool; // { dg-error "invalid cast .u8. to .bool. \\\[E0054\\\]" } - let nc = true as char; // { dg-error "invalid cast" } + let nb = 0u8 as bool; // { dg-error "cannot cast .u8. as .bool." } + let nc = true as char; // { dg-error "cannot cast .bool. as .char., only .u8. can be cast as .char." } let a = 'a'; let b = 'b'; - let fa = a as f32; // { dg-error "invalid cast" } - let bb = b as bool; // { dg-error "invalid cast .char. to .bool. \\\[E0054\\\]" } + let fa = a as f32; // { dg-error "casting .char. as .f32. is invalid" } + let bb = b as bool; // { dg-error "cannot cast .char. as .bool." } let t32: u32 = 33; - let ab = t32 as char; // { dg-error "invalid cast" } + let ab = t32 as char; // { dg-error "cannot cast .u32. as .char., only .u8. can be cast as .char." } } diff --git a/gcc/testsuite/rust/compile/cast1.rs b/gcc/testsuite/rust/compile/cast1.rs index 74c4b1eaac4c..0472d582db84 100644 --- a/gcc/testsuite/rust/compile/cast1.rs +++ b/gcc/testsuite/rust/compile/cast1.rs @@ -1,5 +1,5 @@ fn main() { let a: i32 = 123; let b = a as char; - // { dg-error "invalid cast .i32. to .char." "" { target *-*-* } .-1 } + // { dg-error "cannot cast .i32. as .char., only .u8. can be cast as .char." "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/rust/compile/cast4.rs b/gcc/testsuite/rust/compile/cast4.rs index ab00010e35b1..22ac0c5acf7e 100644 --- a/gcc/testsuite/rust/compile/cast4.rs +++ b/gcc/testsuite/rust/compile/cast4.rs @@ -1,5 +1,5 @@ fn main() { let a: i32 = 123; let u = a as bool; - // { dg-error "invalid cast .i32. to .bool." "" { target *-*-* } .-1 } + // { dg-error "cannot cast .i32. as .bool." "" { target *-*-* } .-1 } } diff --git a/gcc/testsuite/rust/compile/cast5.rs b/gcc/testsuite/rust/compile/cast5.rs index ecc10c1490a6..2e340dd4fe4b 100644 --- a/gcc/testsuite/rust/compile/cast5.rs +++ b/gcc/testsuite/rust/compile/cast5.rs @@ -1,11 +1,11 @@ fn main() { const A: char = 0x1F888 as char; - // { dg-error "invalid cast .. to .char." "" { target *-*-* } .-1 } + // { dg-error "cannot cast .. as .char., only .u8. can be cast as .char." "" { target *-*-* } .-1 } const B: char = 129160 as char; - // { dg-error "invalid cast .. to .char." "" { target *-*-* } .-1 } + // { dg-error "cannot cast .. as .char., only .u8. can be cast as .char." "" { target *-*-* } .-1 } const C: i32 = 42; const D: char = C as char; - // { dg-error "invalid cast .i32. to .char." "" { target *-*-* } .-1 } + // { dg-error "cannot cast .i32. as .char., only .u8. can be cast as .char." "" { target *-*-* } .-1 } const E: char = '\u{01F888}'; const F: u8 = 42; const G: char= F as char;