Skip to content

Commit 0f695f7

Browse files
committed
Add suggest alternatives for Out-of-range \x escapes
1 parent 27b076a commit 0f695f7

File tree

6 files changed

+117
-9
lines changed

6 files changed

+117
-9
lines changed

compiler/rustc_parse/messages.ftl

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -732,8 +732,6 @@ parse_or_in_let_chain = `||` operators are not supported in let chain conditions
732732
733733
parse_or_pattern_not_allowed_in_fn_parameters = function parameters require top-level or-patterns in parentheses
734734
parse_or_pattern_not_allowed_in_let_binding = `let` bindings require top-level or-patterns in parentheses
735-
parse_out_of_range_hex_escape = out of range hex escape
736-
.label = must be a character in the range [\x00-\x7f]
737735
738736
parse_outer_attr_explanation = outer attributes, like `#[test]`, annotate the item following them
739737

compiler/rustc_parse/src/errors.rs

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2455,12 +2455,6 @@ pub(crate) enum UnescapeError {
24552455
is_hex: bool,
24562456
ch: String,
24572457
},
2458-
#[diag(parse_out_of_range_hex_escape)]
2459-
OutOfRangeHexEscape(
2460-
#[primary_span]
2461-
#[label]
2462-
Span,
2463-
),
24642458
#[diag(parse_leading_underscore_unicode_escape)]
24652459
LeadingUnderscoreUnicodeEscape {
24662460
#[primary_span]

compiler/rustc_parse/src/lexer/unescape_error_reporting.rs

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,24 @@ pub(crate) fn emit_unescape_error(
226226
err.emit()
227227
}
228228
EscapeError::OutOfRangeHexEscape => {
229-
dcx.emit_err(UnescapeError::OutOfRangeHexEscape(err_span))
229+
let mut err = dcx.struct_span_err(err_span, "out of range hex escape");
230+
err.span_label(err_span, "must be a character in the range [\\x00-\\x7f]");
231+
232+
let escape_str = &lit[range];
233+
if lit.len() <= 4
234+
&& escape_str.len() == 4
235+
&& escape_str.starts_with("\\x")
236+
&& let Ok(value) = u8::from_str_radix(&escape_str[2..4], 16)
237+
&& matches!(mode, Mode::Char | Mode::Str)
238+
{
239+
err.help(format!("if you want to write a byte literal, use `b'{}'`", escape_str));
240+
err.help(format!(
241+
"if you want to write a Unicode character, use `'\\u{{{:X}}}'`",
242+
value
243+
));
244+
}
245+
246+
err.emit()
230247
}
231248
EscapeError::LeadingUnderscoreUnicodeEscape => {
232249
let (c, span) = last_char();

tests/ui/parser/ascii-only-character-escape.stderr

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,18 +3,27 @@ error: out of range hex escape
33
|
44
LL | let x = "\x80";
55
| ^^^^ must be a character in the range [\x00-\x7f]
6+
|
7+
= help: if you want to write a byte literal, use `b'\x80'`
8+
= help: if you want to write a Unicode character, use `'\u{80}'`
69

710
error: out of range hex escape
811
--> $DIR/ascii-only-character-escape.rs:3:14
912
|
1013
LL | let y = "\xff";
1114
| ^^^^ must be a character in the range [\x00-\x7f]
15+
|
16+
= help: if you want to write a byte literal, use `b'\xff'`
17+
= help: if you want to write a Unicode character, use `'\u{FF}'`
1218

1319
error: out of range hex escape
1420
--> $DIR/ascii-only-character-escape.rs:4:14
1521
|
1622
LL | let z = "\xe2";
1723
| ^^^^ must be a character in the range [\x00-\x7f]
24+
|
25+
= help: if you want to write a byte literal, use `b'\xe2'`
26+
= help: if you want to write a Unicode character, use `'\u{E2}'`
1827

1928
error: aborting due to 3 previous errors
2029

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
fn main() {
2+
let _c = '\xFF'; //~ ERROR out of range hex escape
3+
let _s = "\xFF"; //~ ERROR out of range hex escape
4+
5+
let _c2 = '\xff'; //~ ERROR out of range hex escape
6+
let _s2 = "\xff"; //~ ERROR out of range hex escape
7+
8+
let _c3 = '\x80'; //~ ERROR out of range hex escape
9+
let _s3 = "\x80"; //~ ERROR out of range hex escape
10+
11+
// Byte literals should not get suggestions (they're already valid)
12+
let _b = b'\xFF'; // OK
13+
let _bs = b"\xFF"; // OK
14+
15+
dbg!('\xFF'); //~ ERROR out of range hex escape
16+
17+
// do not suggest for out of range escapes that are too long
18+
dbg!("\xFFFFF"); //~ ERROR out of range hex escape
19+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
error: out of range hex escape
2+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:2:15
3+
|
4+
LL | let _c = '\xFF';
5+
| ^^^^ must be a character in the range [\x00-\x7f]
6+
|
7+
= help: if you want to write a byte literal, use `b'\xFF'`
8+
= help: if you want to write a Unicode character, use `'\u{FF}'`
9+
10+
error: out of range hex escape
11+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:3:15
12+
|
13+
LL | let _s = "\xFF";
14+
| ^^^^ must be a character in the range [\x00-\x7f]
15+
|
16+
= help: if you want to write a byte literal, use `b'\xFF'`
17+
= help: if you want to write a Unicode character, use `'\u{FF}'`
18+
19+
error: out of range hex escape
20+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:5:16
21+
|
22+
LL | let _c2 = '\xff';
23+
| ^^^^ must be a character in the range [\x00-\x7f]
24+
|
25+
= help: if you want to write a byte literal, use `b'\xff'`
26+
= help: if you want to write a Unicode character, use `'\u{FF}'`
27+
28+
error: out of range hex escape
29+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:6:16
30+
|
31+
LL | let _s2 = "\xff";
32+
| ^^^^ must be a character in the range [\x00-\x7f]
33+
|
34+
= help: if you want to write a byte literal, use `b'\xff'`
35+
= help: if you want to write a Unicode character, use `'\u{FF}'`
36+
37+
error: out of range hex escape
38+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:8:16
39+
|
40+
LL | let _c3 = '\x80';
41+
| ^^^^ must be a character in the range [\x00-\x7f]
42+
|
43+
= help: if you want to write a byte literal, use `b'\x80'`
44+
= help: if you want to write a Unicode character, use `'\u{80}'`
45+
46+
error: out of range hex escape
47+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:9:16
48+
|
49+
LL | let _s3 = "\x80";
50+
| ^^^^ must be a character in the range [\x00-\x7f]
51+
|
52+
= help: if you want to write a byte literal, use `b'\x80'`
53+
= help: if you want to write a Unicode character, use `'\u{80}'`
54+
55+
error: out of range hex escape
56+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:15:11
57+
|
58+
LL | dbg!('\xFF');
59+
| ^^^^ must be a character in the range [\x00-\x7f]
60+
|
61+
= help: if you want to write a byte literal, use `b'\xFF'`
62+
= help: if you want to write a Unicode character, use `'\u{FF}'`
63+
64+
error: out of range hex escape
65+
--> $DIR/out-of-range-hex-escape-suggestions-148917.rs:18:11
66+
|
67+
LL | dbg!("\xFFFFF");
68+
| ^^^^ must be a character in the range [\x00-\x7f]
69+
70+
error: aborting due to 8 previous errors
71+

0 commit comments

Comments
 (0)