diff options
| author | Josh Stone <cuviper@gmail.com> | 2023-08-17 15:40:09 -0700 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2023-08-17 15:40:09 -0700 |
| commit | 7ea4de9632ab0e29e34e5250f367992a0e862519 (patch) | |
| tree | 2cb3ed6267dc626eb38d2897b1f35ce47b4d33c4 | |
| parent | 4f14451d7ca4265be1b39c7f4ec63fb28ff6bc70 (diff) | |
| parent | 072d8c8bbc57358ffd6fa66f6a12365464de185f (diff) | |
| download | rust-7ea4de9632ab0e29e34e5250f367992a0e862519.tar.gz rust-7ea4de9632ab0e29e34e5250f367992a0e862519.zip | |
Rollup merge of #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.
| -rw-r--r-- | compiler/rustc_parse/src/lexer/unescape_error_reporting.rs | 22 | ||||
| -rw-r--r-- | tests/ui/inference/str-as-char.fixed | 1 | ||||
| -rw-r--r-- | tests/ui/inference/str-as-char.rs | 1 | ||||
| -rw-r--r-- | tests/ui/inference/str-as-char.stderr | 13 |
4 files changed, 22 insertions, 15 deletions
diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 446472d1294..b659c40b233 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -80,20 +80,14 @@ pub(crate) fn emit_unescape_error( let sugg = sugg.unwrap_or_else(|| { let prefix = mode.prefix_noraw(); let mut escaped = String::with_capacity(lit.len()); - let mut chrs = lit.chars().peekable(); - while let Some(first) = chrs.next() { - match (first, chrs.peek()) { - ('\\', Some('"')) => { - escaped.push('\\'); - escaped.push('"'); - chrs.next(); - } - ('"', _) => { - escaped.push('\\'); - escaped.push('"') - } - (c, _) => escaped.push(c), - }; + let mut in_escape = false; + for c in lit.chars() { + match c { + '\\' => in_escape = !in_escape, + '"' if !in_escape => escaped.push('\\'), + _ => in_escape = false, + } + escaped.push(c); } let sugg = format!("{prefix}\"{escaped}\""); MoreThanOneCharSugg::Quotes { diff --git a/tests/ui/inference/str-as-char.fixed b/tests/ui/inference/str-as-char.fixed index 6aea809cbdb..911b067c4d1 100644 --- a/tests/ui/inference/str-as-char.fixed +++ b/tests/ui/inference/str-as-char.fixed @@ -7,4 +7,5 @@ fn main() { let _: &str = "a"; //~ ERROR mismatched types let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint let _: &str = "\"\"\""; //~ ERROR character literal may only contain one codepoint + let _: &str = "\"\"\\\"\\\"\\\\\""; //~ ERROR character literal may only contain one codepoint } diff --git a/tests/ui/inference/str-as-char.rs b/tests/ui/inference/str-as-char.rs index eaa8d788c34..832bc871a9e 100644 --- a/tests/ui/inference/str-as-char.rs +++ b/tests/ui/inference/str-as-char.rs @@ -7,4 +7,5 @@ fn main() { let _: &str = 'a'; //~ ERROR mismatched types let _: &str = '"""'; //~ ERROR character literal may only contain one codepoint let _: &str = '\"\"\"'; //~ ERROR character literal may only contain one codepoint + let _: &str = '"\"\\"\\\"\\\\"'; //~ ERROR character literal may only contain one codepoint } diff --git a/tests/ui/inference/str-as-char.stderr b/tests/ui/inference/str-as-char.stderr index 2c84dac8e0c..216f4cda698 100644 --- a/tests/ui/inference/str-as-char.stderr +++ b/tests/ui/inference/str-as-char.stderr @@ -20,6 +20,17 @@ help: if you meant to write a `str` literal, use double quotes LL | let _: &str = "\"\"\""; | ~~~~~~~~ +error: character literal may only contain one codepoint + --> $DIR/str-as-char.rs:10:19 + | +LL | let _: &str = '"\"\"\\"\\"'; + | ^^^^^^^^^^^^^^^^^ + | +help: if you meant to write a `str` literal, use double quotes + | +LL | let _: &str = "\"\"\\"\\"\\\""; + | ~~~~~~~~~~~~~~~~~~~~ + error[E0308]: mismatched types --> $DIR/str-as-char.rs:7:19 | @@ -33,6 +44,6 @@ help: if you meant to write a `str` literal, use double quotes LL | let _: &str = "a"; | ~~~ -error: aborting due to 3 previous errors +error: aborting due to 4 previous errors For more information about this error, try `rustc --explain E0308`. |
