Skip to content

Commit 0e3af6a

Browse files
authored
Rollup merge of #107709 - tialaramex:master, r=compiler-errors
Fix problem noticed in PR106859 with char -> u8 suggestion HN reader `@ayosec` noticed that my #106859 a few weeks back, malfunctions if you have a Unicode escape, the code suggested b'\u{0}' if you tried to use '\u{0}' where a byte should be, when of course b'\u{0}' is not a byte literal, regardless of the codepoint you can't write Unicode escapes in a byte literal at all. My proposed fix here just checks that the "character" you wrote is fewer than 5 bytes, thus allowing \x7F and similar escapes but conveniently forbidding even the smallest Unicode escape \u{0} before offering the suggestion as before. I have provided an updated test which includes examples which do and don't work because of this additional rule.
2 parents e45984b + 747cdc0 commit 0e3af6a

File tree

3 files changed

+57
-3
lines changed

3 files changed

+57
-3
lines changed

compiler/rustc_infer/src/infer/error_reporting/mod.rs

+2-1
Original file line numberDiff line numberDiff line change
@@ -1922,7 +1922,8 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
19221922
(ty::Uint(ty::UintTy::U8), ty::Char) => {
19231923
if let Ok(code) = self.tcx.sess().source_map().span_to_snippet(span)
19241924
&& let Some(code) = code.strip_prefix('\'').and_then(|s| s.strip_suffix('\''))
1925-
&& code.chars().next().map_or(false, |c| c.is_ascii())
1925+
&& !code.starts_with("\\u") // forbid all Unicode escapes
1926+
&& code.chars().next().map_or(false, |c| c.is_ascii()) // forbids literal Unicode characters beyond ASCII
19261927
{
19271928
err.span_suggestion(
19281929
span,

tests/ui/suggestions/type-mismatch-byte-literal.rs

+12
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,19 @@ fn main() {
1212
//~^ ERROR: mismatched types [E0308]
1313
//~| HELP: if you meant to write a byte literal, prefix with `b`
1414

15+
let _a: u8 = '\x20';
16+
//~^ ERROR: mismatched types [E0308]
17+
//~| HELP: if you meant to write a byte literal, prefix with `b`
18+
19+
// Do not issue the suggestion if the char literal is a Unicode escape
20+
foo('\u{0080}');
21+
//~^ ERROR: mismatched types [E0308]
22+
1523
// Do not issue the suggestion if the char literal isn't ASCII
1624
let _t: u8 = '€';
1725
//~^ ERROR: mismatched types [E0308]
26+
27+
// Do not issue the suggestion if the char literal isn't ASCII
28+
foo('\u{1f980}');
29+
//~^ ERROR: mismatched types [E0308]
1830
}

tests/ui/suggestions/type-mismatch-byte-literal.stderr

+43-2
Original file line numberDiff line numberDiff line change
@@ -30,13 +30,54 @@ LL | foo(b'#');
3030
| ~~~~
3131

3232
error[E0308]: mismatched types
33-
--> $DIR/type-mismatch-byte-literal.rs:16:18
33+
--> $DIR/type-mismatch-byte-literal.rs:15:18
34+
|
35+
LL | let _a: u8 = '\x20';
36+
| -- ^^^^^^ expected `u8`, found `char`
37+
| |
38+
| expected due to this
39+
|
40+
help: if you meant to write a byte literal, prefix with `b`
41+
|
42+
LL | let _a: u8 = b'\x20';
43+
| ~~~~~~~
44+
45+
error[E0308]: mismatched types
46+
--> $DIR/type-mismatch-byte-literal.rs:20:9
47+
|
48+
LL | foo('\u{0080}');
49+
| --- ^^^^^^^^^^ expected `u8`, found `char`
50+
| |
51+
| arguments to this function are incorrect
52+
|
53+
note: function defined here
54+
--> $DIR/type-mismatch-byte-literal.rs:4:4
55+
|
56+
LL | fn foo(_t: u8) {}
57+
| ^^^ ------
58+
59+
error[E0308]: mismatched types
60+
--> $DIR/type-mismatch-byte-literal.rs:24:18
3461
|
3562
LL | let _t: u8 = '€';
3663
| -- ^^^ expected `u8`, found `char`
3764
| |
3865
| expected due to this
3966

40-
error: aborting due to 3 previous errors
67+
error[E0308]: mismatched types
68+
--> $DIR/type-mismatch-byte-literal.rs:28:9
69+
|
70+
LL | foo('\u{1f980}');
71+
| --- ^^^^^^^^^^^ expected `u8`, found `char`
72+
| |
73+
| arguments to this function are incorrect
74+
|
75+
note: function defined here
76+
--> $DIR/type-mismatch-byte-literal.rs:4:4
77+
|
78+
LL | fn foo(_t: u8) {}
79+
| ^^^ ------
80+
81+
error: aborting due to 6 previous errors
4182

4283
For more information about this error, try `rustc --explain E0308`.

0 commit comments

Comments
 (0)