Skip to content

Commit 7ea4de9

Browse files
authored
Rollup merge of rust-lang#114913 - beetrees:escape-double-quote, r=davidtwco
Fix suggestion for attempting to define a string with single quotes Currently attempting to compile `fn main() { let _ = '\\"'; }` will result in the following error message: ``` error: character literal may only contain one codepoint --> src/main.rs:1:21 | 1 | fn main() { let _ = '\\"'; } | ^^^^^ | help: if you meant to write a `str` literal, use double quotes | 1 | fn main() { let _ = "\\""; } | ~~~~~ ``` The suggestion is invalid as it fails to escape the `"`. This PR fixes the suggestion so that it now reads: ``` help: if you meant to write a `str` literal, use double quotes | 1 | fn main() { let _ = "\\\""; } | ~~~~~~ ``` The relevant test is also updated to ensure that this does not regress in future.
2 parents 4f14451 + 072d8c8 commit 7ea4de9

File tree

4 files changed

+22
-15
lines changed

4 files changed

+22
-15
lines changed

compiler/rustc_parse/src/lexer/unescape_error_reporting.rs

+8-14
Original file line numberDiff line numberDiff line change
@@ -80,20 +80,14 @@ pub(crate) fn emit_unescape_error(
8080
let sugg = sugg.unwrap_or_else(|| {
8181
let prefix = mode.prefix_noraw();
8282
let mut escaped = String::with_capacity(lit.len());
83-
let mut chrs = lit.chars().peekable();
84-
while let Some(first) = chrs.next() {
85-
match (first, chrs.peek()) {
86-
('\\', Some('"')) => {
87-
escaped.push('\\');
88-
escaped.push('"');
89-
chrs.next();
90-
}
91-
('"', _) => {
92-
escaped.push('\\');
93-
escaped.push('"')
94-
}
95-
(c, _) => escaped.push(c),
96-
};
83+
let mut in_escape = false;
84+
for c in lit.chars() {
85+
match c {
86+
'\\' => in_escape = !in_escape,
87+
'"' if !in_escape => escaped.push('\\'),
88+
_ => in_escape = false,
89+
}
90+
escaped.push(c);
9791
}
9892
let sugg = format!("{prefix}\"{escaped}\"");
9993
MoreThanOneCharSugg::Quotes {

tests/ui/inference/str-as-char.fixed

+1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ fn main() {
77
let _: &str = "a"; //~ ERROR mismatched types
88
let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint
99
let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint
10+
let _: &str = "\"\"\\\"\\\"\\\\\""; //~ ERROR character literal may only contain one codepoint
1011
}

tests/ui/inference/str-as-char.rs

+1
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,5 @@ fn main() {
77
let _: &str = 'a'; //~ ERROR mismatched types
88
let _: &str = '"""'; //~ ERROR character literal may only contain one codepoint
99
let _: &str = '\"\"\"'; //~ ERROR character literal may only contain one codepoint
10+
let _: &str = '"\"\\"\\\"\\\\"'; //~ ERROR character literal may only contain one codepoint
1011
}

tests/ui/inference/str-as-char.stderr

+12-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,17 @@ help: if you meant to write a `str` literal, use double quotes
2020
LL | let _: &str = "\"\"\"";
2121
| ~~~~~~~~
2222

23+
error: character literal may only contain one codepoint
24+
--> $DIR/str-as-char.rs:10:19
25+
|
26+
LL | let _: &str = '"\"\"\\"\\"';
27+
| ^^^^^^^^^^^^^^^^^
28+
|
29+
help: if you meant to write a `str` literal, use double quotes
30+
|
31+
LL | let _: &str = "\"\"\\"\\"\\\"";
32+
| ~~~~~~~~~~~~~~~~~~~~
33+
2334
error[E0308]: mismatched types
2435
--> $DIR/str-as-char.rs:7:19
2536
|
@@ -33,6 +44,6 @@ help: if you meant to write a `str` literal, use double quotes
3344
LL | let _: &str = "a";
3445
| ~~~
3546

36-
error: aborting due to 3 previous errors
47+
error: aborting due to 4 previous errors
3748

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

0 commit comments

Comments
 (0)