diff options
| author | Matthias Krüger <matthias.krueger@famsik.de> | 2022-10-23 08:14:31 +0200 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2022-10-23 08:14:31 +0200 |
| commit | b656f5e9a64d6fe0f0b75e76e6350fb08cea562d (patch) | |
| tree | 649aff2c2c3392d57c0c43afb76d563945fb534c | |
| parent | 1a077420f864868ec0c8b5d401a4dbb60f18c77d (diff) | |
| parent | 876248506c9dcb0f4f57db49021374bb0bfc1bd7 (diff) | |
| download | rust-b656f5e9a64d6fe0f0b75e76e6350fb08cea562d.tar.gz rust-b656f5e9a64d6fe0f0b75e76e6350fb08cea562d.zip | |
Rollup merge of #103354 - clubby789:escape-string-literals, r=compiler-errors
Escape string literals when fixing overlong char literal Fixes #103323 ````@rustbot```` label +A-diagnostics +A-suggestion-diagnostics
| -rw-r--r-- | compiler/rustc_infer/src/infer/error_reporting/mod.rs | 23 | ||||
| -rw-r--r-- | compiler/rustc_parse/src/lexer/unescape_error_reporting.rs | 19 | ||||
| -rw-r--r-- | src/test/ui/inference/char-as-str-single.fixed | 1 | ||||
| -rw-r--r-- | src/test/ui/inference/char-as-str-single.rs | 1 | ||||
| -rw-r--r-- | src/test/ui/inference/char-as-str-single.stderr | 15 | ||||
| -rw-r--r-- | src/test/ui/inference/str-as-char.fixed | 4 | ||||
| -rw-r--r-- | src/test/ui/inference/str-as-char.rs | 4 | ||||
| -rw-r--r-- | src/test/ui/inference/str-as-char.stderr | 24 |
8 files changed, 83 insertions, 8 deletions
diff --git a/compiler/rustc_infer/src/infer/error_reporting/mod.rs b/compiler/rustc_infer/src/infer/error_reporting/mod.rs index 2fe6f63a9c6..9ff703e521f 100644 --- a/compiler/rustc_infer/src/infer/error_reporting/mod.rs +++ b/compiler/rustc_infer/src/infer/error_reporting/mod.rs @@ -2271,6 +2271,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str) } FailureCode::Error0308(failure_str) => { + fn escape_literal(s: &str) -> String { + let mut escaped = String::with_capacity(s.len()); + let mut chrs = s.chars().peekable(); + while let Some(first) = chrs.next() { + match (first, chrs.peek()) { + ('\\', Some(&delim @ '"') | Some(&delim @ '\'')) => { + escaped.push('\\'); + escaped.push(delim); + chrs.next(); + } + ('"' | '\'', _) => { + escaped.push('\\'); + escaped.push(first) + } + (c, _) => escaped.push(c), + }; + } + escaped + } let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str); if let Some((expected, found)) = trace.values.ty() { match (expected.kind(), found.kind()) { @@ -2292,7 +2311,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.span_suggestion( span, "if you meant to write a `char` literal, use single quotes", - format!("'{}'", code), + format!("'{}'", escape_literal(code)), Applicability::MachineApplicable, ); } @@ -2307,7 +2326,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> { err.span_suggestion( span, "if you meant to write a `str` literal, use double quotes", - format!("\"{}\"", code), + format!("\"{}\"", escape_literal(code)), Applicability::MachineApplicable, ); } diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index 77c4fadab45..f075de71426 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -113,11 +113,26 @@ pub(crate) fn emit_unescape_error( } else { ("", "if you meant to write a `str` literal, use double quotes") }; - + 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), + }; + } handler.span_suggestion( span_with_quotes, msg, - format!("{}\"{}\"", prefix, lit), + format!("{prefix}\"{escaped}\""), Applicability::MachineApplicable, ); } diff --git a/src/test/ui/inference/char-as-str-single.fixed b/src/test/ui/inference/char-as-str-single.fixed index e401492a830..bab1854dc51 100644 --- a/src/test/ui/inference/char-as-str-single.fixed +++ b/src/test/ui/inference/char-as-str-single.fixed @@ -8,4 +8,5 @@ fn main() { let _: char = 'a'; //~ ERROR mismatched types let _: char = '人'; //~ ERROR mismatched types + let _: char = '\''; //~ ERROR mismatched types } diff --git a/src/test/ui/inference/char-as-str-single.rs b/src/test/ui/inference/char-as-str-single.rs index 4f23cea5354..736920643b2 100644 --- a/src/test/ui/inference/char-as-str-single.rs +++ b/src/test/ui/inference/char-as-str-single.rs @@ -8,4 +8,5 @@ fn main() { let _: char = "a"; //~ ERROR mismatched types let _: char = "人"; //~ ERROR mismatched types + let _: char = "'"; //~ ERROR mismatched types } diff --git a/src/test/ui/inference/char-as-str-single.stderr b/src/test/ui/inference/char-as-str-single.stderr index 29075c15414..3375ec6ac32 100644 --- a/src/test/ui/inference/char-as-str-single.stderr +++ b/src/test/ui/inference/char-as-str-single.stderr @@ -24,6 +24,19 @@ help: if you meant to write a `char` literal, use single quotes LL | let _: char = '人'; | ~~~~ -error: aborting due to 2 previous errors +error[E0308]: mismatched types + --> $DIR/char-as-str-single.rs:11:19 + | +LL | let _: char = "'"; + | ---- ^^^ expected `char`, found `&str` + | | + | expected due to this + | +help: if you meant to write a `char` literal, use single quotes + | +LL | let _: char = '\''; + | ~~~~ + +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. diff --git a/src/test/ui/inference/str-as-char.fixed b/src/test/ui/inference/str-as-char.fixed index 09f3dec5a17..6aea809cbdb 100644 --- a/src/test/ui/inference/str-as-char.fixed +++ b/src/test/ui/inference/str-as-char.fixed @@ -4,5 +4,7 @@ // run-rustfix fn main() { - let _: &str = "a"; //~ ERROR mismatched types + 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 } diff --git a/src/test/ui/inference/str-as-char.rs b/src/test/ui/inference/str-as-char.rs index 7092a612442..eaa8d788c34 100644 --- a/src/test/ui/inference/str-as-char.rs +++ b/src/test/ui/inference/str-as-char.rs @@ -4,5 +4,7 @@ // run-rustfix fn main() { - let _: &str = 'a'; //~ ERROR mismatched types + 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 } diff --git a/src/test/ui/inference/str-as-char.stderr b/src/test/ui/inference/str-as-char.stderr index ebbe7c80f77..2c84dac8e0c 100644 --- a/src/test/ui/inference/str-as-char.stderr +++ b/src/test/ui/inference/str-as-char.stderr @@ -1,3 +1,25 @@ +error: character literal may only contain one codepoint + --> $DIR/str-as-char.rs:8:19 + | +LL | let _: &str = '"""'; + | ^^^^^ + | +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:9: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 | @@ -11,6 +33,6 @@ help: if you meant to write a `str` literal, use double quotes LL | let _: &str = "a"; | ~~~ -error: aborting due to previous error +error: aborting due to 3 previous errors For more information about this error, try `rustc --explain E0308`. |
