Skip to content

Commit

Permalink
Rollup merge of rust-lang#91939 - GKFX:feature-91866, r=cjgillot
Browse files Browse the repository at this point in the history
Clarify error on casting larger integers to char

Closes rust-lang#91836 with changes to E0604.md and a `span_help`.
  • Loading branch information
matthiaskrgr authored Feb 5, 2022
2 parents 291bf94 + badb81a commit 8cdf44a
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 7 deletions.
11 changes: 8 additions & 3 deletions compiler/rustc_error_codes/src/error_codes/E0604.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ Erroneous code example:
0u32 as char; // error: only `u8` can be cast as `char`, not `u32`
```

As the error message indicates, only `u8` can be cast into `char`. Example:
`char` is a Unicode Scalar Value, an integer value from 0 to 0xD7FF and
0xE000 to 0x10FFFF. (The gap is for surrogate pairs.) Only `u8` always fits in
those ranges so only `u8` may be cast to `char`.

To allow larger values, use `char::from_u32`, which checks the value is valid.

```
let c = 86u8 as char; // ok!
assert_eq!(c, 'V');
assert_eq!(86u8 as char, 'V'); // ok!
assert_eq!(char::from_u32(0x3B1), Some('α')); // ok!
assert_eq!(char::from_u32(0xD800), None); // not a USV.
```

For more information about casts, take a look at the Type cast section in
Expand Down
20 changes: 16 additions & 4 deletions compiler/rustc_typeck/src/check/cast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -328,16 +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")
.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!(
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/consts/const-eval/const-eval-overflow-4b.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/error-codes/E0604.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/error-festival.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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<u8>`
--> $DIR/error-festival.rs:29:5
Expand Down
6 changes: 6 additions & 0 deletions src/test/ui/mismatched_types/cast-rfc0401.stderr
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 8cdf44a

Please sign in to comment.