about summary refs log tree commit diff
path: root/tests
diff options
context:
space:
mode:
authorLeón Orell Valerian Liehr <me@fmease.dev>2025-07-17 03:58:31 +0200
committerGitHub <noreply@github.com>2025-07-17 03:58:31 +0200
commitfe420b05e39450c35d65fc6cc536e16d84025eb2 (patch)
tree6af02622a74ed2deeb12f5e7d1bb9b13ef83f01b /tests
parent83288db888606371dfac6491fc5720d31774aa8c (diff)
parent81a6f189408b71b452a9804818f2cd50d2ed9108 (diff)
downloadrust-fe420b05e39450c35d65fc6cc536e16d84025eb2.tar.gz
rust-fe420b05e39450c35d65fc6cc536e16d84025eb2.zip
Rollup merge of #143678 - Kivooeo:char-overflow, r=SparrowLii
Added error for invalid char cast

fixes rust-lang/rust#143597

not really sure if I did it right, but according to cast-char test -- it is right, also this code gave me false positive result

```
for _ in 0..(256 as u8) {}
```

so this is why I added this check `if lit_val <= 0xFF`

Also I believe that error message could be improved, but I'm not sure how exactly

cc ```@hkBst```

r? compiler
Diffstat (limited to 'tests')
-rw-r--r--tests/ui/cast/cast-char.rs56
-rw-r--r--tests/ui/cast/cast-char.stderr124
2 files changed, 169 insertions, 11 deletions
diff --git a/tests/ui/cast/cast-char.rs b/tests/ui/cast/cast-char.rs
index 9634ed56f7b..5bf05072253 100644
--- a/tests/ui/cast/cast-char.rs
+++ b/tests/ui/cast/cast-char.rs
@@ -1,10 +1,58 @@
 #![deny(overflowing_literals)]
 
 fn main() {
-    const XYZ: char = 0x1F888 as char;
+    // Valid cases - should suggest char literal
+
+    // u8 range (0-255)
+    const VALID_U8_1: char = 0x41 as char; // 'A'
+    const VALID_U8_2: char = 0xFF as char; // maximum u8
+    const VALID_U8_3: char = 0x00 as char; // minimum u8
+
+    // Valid Unicode in lower range [0x0, 0xD7FF]
+    const VALID_LOW_1: char = 0x1000 as char; // 4096
+    //~^ ERROR: only `u8` can be cast into `char`
+    const VALID_LOW_2: char = 0xD7FF as char; // last valid in lower range
+    //~^ ERROR: only `u8` can be cast into `char`
+    const VALID_LOW_3: char = 0x0500 as char; // cyrillic range
+    //~^ ERROR: only `u8` can be cast into `char`
+
+    // Valid Unicode in upper range [0xE000, 0x10FFFF]
+    const VALID_HIGH_1: char = 0xE000 as char; // first valid in upper range
+    //~^ ERROR only `u8` can be cast into `char`
+    const VALID_HIGH_2: char = 0x1F888 as char; // 129160 - example from issue
+    //~^ ERROR only `u8` can be cast into `char`
+    const VALID_HIGH_3: char = 0x10FFFF as char; // maximum valid Unicode
+    //~^ ERROR only `u8` can be cast into `char`
+    const VALID_HIGH_4: char = 0xFFFD as char; // replacement character
+    //~^ ERROR only `u8` can be cast into `char`
+    const VALID_HIGH_5: char = 0x1F600 as char; // emoji
+    //~^ ERROR only `u8` can be cast into `char`
+
+    // Invalid cases - should show InvalidCharCast
+
+    // Surrogate range [0xD800, 0xDFFF] - reserved for UTF-16
+    const INVALID_SURROGATE_1: char = 0xD800 as char; // first surrogate
+    //~^ ERROR: surrogate values are not valid
+    const INVALID_SURROGATE_2: char = 0xDFFF as char; // last surrogate
+    //~^ ERROR: surrogate values are not valid
+    const INVALID_SURROGATE_3: char = 0xDB00 as char; // middle of surrogate range
+    //~^ ERROR: surrogate values are not valid
+
+    // Too large values (> 0x10FFFF)
+    const INVALID_TOO_BIG_1: char = 0x110000 as char; // one more than maximum
+    //~^ ERROR: value exceeds maximum `char` value
+    const INVALID_TOO_BIG_2: char = 0xEF8888 as char; // example from issue
+    //~^ ERROR: value exceeds maximum `char` value
+    const INVALID_TOO_BIG_3: char = 0x1FFFFF as char; // much larger
+    //~^ ERROR: value exceeds maximum `char` value
+    const INVALID_TOO_BIG_4: char = 0xFFFFFF as char; // 24-bit maximum
+    //~^ ERROR: value exceeds maximum `char` value
+
+    // Boundary cases
+    const BOUNDARY_1: char = 0xD7FE as char; // valid, before surrogate
+    //~^ ERROR only `u8` can be cast into `char`
+    const BOUNDARY_2: char = 0xE001 as char; // valid, after surrogate
     //~^ ERROR only `u8` can be cast into `char`
-    const XY: char = 129160 as char;
+    const BOUNDARY_3: char = 0x10FFFE as char; // valid, near maximum
     //~^ ERROR only `u8` can be cast into `char`
-    const ZYX: char = '\u{01F888}';
-    println!("{}", XYZ);
 }
diff --git a/tests/ui/cast/cast-char.stderr b/tests/ui/cast/cast-char.stderr
index 211937c9d6f..a8d0b3b04b0 100644
--- a/tests/ui/cast/cast-char.stderr
+++ b/tests/ui/cast/cast-char.stderr
@@ -1,8 +1,8 @@
 error: only `u8` can be cast into `char`
-  --> $DIR/cast-char.rs:4:23
+  --> $DIR/cast-char.rs:12:31
    |
-LL |     const XYZ: char = 0x1F888 as char;
-   |                       ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'`
+LL |     const VALID_LOW_1: char = 0x1000 as char; // 4096
+   |                               ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1000}'`
    |
 note: the lint level is defined here
   --> $DIR/cast-char.rs:1:9
@@ -11,10 +11,120 @@ LL | #![deny(overflowing_literals)]
    |         ^^^^^^^^^^^^^^^^^^^^
 
 error: only `u8` can be cast into `char`
-  --> $DIR/cast-char.rs:6:22
+  --> $DIR/cast-char.rs:14:31
    |
-LL |     const XY: char = 129160 as char;
-   |                      ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'`
+LL |     const VALID_LOW_2: char = 0xD7FF as char; // last valid in lower range
+   |                               ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{D7FF}'`
 
-error: aborting due to 2 previous errors
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:16:31
+   |
+LL |     const VALID_LOW_3: char = 0x0500 as char; // cyrillic range
+   |                               ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{500}'`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:20:32
+   |
+LL |     const VALID_HIGH_1: char = 0xE000 as char; // first valid in upper range
+   |                                ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{E000}'`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:22:32
+   |
+LL |     const VALID_HIGH_2: char = 0x1F888 as char; // 129160 - example from issue
+   |                                ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F888}'`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:24:32
+   |
+LL |     const VALID_HIGH_3: char = 0x10FFFF as char; // maximum valid Unicode
+   |                                ^^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{10FFFF}'`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:26:32
+   |
+LL |     const VALID_HIGH_4: char = 0xFFFD as char; // replacement character
+   |                                ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{FFFD}'`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:28:32
+   |
+LL |     const VALID_HIGH_5: char = 0x1F600 as char; // emoji
+   |                                ^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{1F600}'`
+
+error: surrogate values are not valid for `char`
+  --> $DIR/cast-char.rs:34:39
+   |
+LL |     const INVALID_SURROGATE_1: char = 0xD800 as char; // first surrogate
+   |                                       ^^^^^^^^^^^^^^
+   |
+   = note: `0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values
+
+error: surrogate values are not valid for `char`
+  --> $DIR/cast-char.rs:36:39
+   |
+LL |     const INVALID_SURROGATE_2: char = 0xDFFF as char; // last surrogate
+   |                                       ^^^^^^^^^^^^^^
+   |
+   = note: `0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values
+
+error: surrogate values are not valid for `char`
+  --> $DIR/cast-char.rs:38:39
+   |
+LL |     const INVALID_SURROGATE_3: char = 0xDB00 as char; // middle of surrogate range
+   |                                       ^^^^^^^^^^^^^^
+   |
+   = note: `0xD800..=0xDFFF` are reserved for Unicode surrogates and are not valid `char` values
+
+error: value exceeds maximum `char` value
+  --> $DIR/cast-char.rs:42:37
+   |
+LL |     const INVALID_TOO_BIG_1: char = 0x110000 as char; // one more than maximum
+   |                                     ^^^^^^^^^^^^^^^^
+   |
+   = note: maximum valid `char` value is `0x10FFFF`
+
+error: value exceeds maximum `char` value
+  --> $DIR/cast-char.rs:44:37
+   |
+LL |     const INVALID_TOO_BIG_2: char = 0xEF8888 as char; // example from issue
+   |                                     ^^^^^^^^^^^^^^^^
+   |
+   = note: maximum valid `char` value is `0x10FFFF`
+
+error: value exceeds maximum `char` value
+  --> $DIR/cast-char.rs:46:37
+   |
+LL |     const INVALID_TOO_BIG_3: char = 0x1FFFFF as char; // much larger
+   |                                     ^^^^^^^^^^^^^^^^
+   |
+   = note: maximum valid `char` value is `0x10FFFF`
+
+error: value exceeds maximum `char` value
+  --> $DIR/cast-char.rs:48:37
+   |
+LL |     const INVALID_TOO_BIG_4: char = 0xFFFFFF as char; // 24-bit maximum
+   |                                     ^^^^^^^^^^^^^^^^
+   |
+   = note: maximum valid `char` value is `0x10FFFF`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:52:30
+   |
+LL |     const BOUNDARY_1: char = 0xD7FE as char; // valid, before surrogate
+   |                              ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{D7FE}'`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:54:30
+   |
+LL |     const BOUNDARY_2: char = 0xE001 as char; // valid, after surrogate
+   |                              ^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{E001}'`
+
+error: only `u8` can be cast into `char`
+  --> $DIR/cast-char.rs:56:30
+   |
+LL |     const BOUNDARY_3: char = 0x10FFFE as char; // valid, near maximum
+   |                              ^^^^^^^^^^^^^^^^ help: use a `char` literal instead: `'\u{10FFFE}'`
+
+error: aborting due to 18 previous errors