Skip to content

Commit ed40d46

Browse files
committed
Properly escape quotes when suggesting switching between char/string literals
1 parent 0940040 commit ed40d46

File tree

2 files changed

+38
-4
lines changed

2 files changed

+38
-4
lines changed

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

+21-2
Original file line numberDiff line numberDiff line change
@@ -2272,6 +2272,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22722272
struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str)
22732273
}
22742274
FailureCode::Error0308(failure_str) => {
2275+
fn escape_literal(s: &str) -> String {
2276+
let mut escaped = String::with_capacity(s.len());
2277+
let mut chrs = s.chars().peekable();
2278+
while let Some(first) = chrs.next() {
2279+
match (first, chrs.peek()) {
2280+
('\\', Some(&delim @ '"') | Some(&delim @ '\'')) => {
2281+
escaped.push('\\');
2282+
escaped.push(delim);
2283+
chrs.next();
2284+
}
2285+
('"' | '\'', _) => {
2286+
escaped.push('\\');
2287+
escaped.push(first)
2288+
}
2289+
(c, _) => escaped.push(c),
2290+
};
2291+
}
2292+
escaped
2293+
}
22752294
let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str);
22762295
if let Some((expected, found)) = trace.values.ty() {
22772296
match (expected.kind(), found.kind()) {
@@ -2293,7 +2312,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
22932312
err.span_suggestion(
22942313
span,
22952314
"if you meant to write a `char` literal, use single quotes",
2296-
format!("'{}'", code),
2315+
format!("'{}'", escape_literal(code)),
22972316
Applicability::MachineApplicable,
22982317
);
22992318
}
@@ -2308,7 +2327,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
23082327
err.span_suggestion(
23092328
span,
23102329
"if you meant to write a `str` literal, use double quotes",
2311-
format!("\"{}\"", code),
2330+
format!("\"{}\"", escape_literal(code)),
23122331
Applicability::MachineApplicable,
23132332
);
23142333
}

compiler/rustc_parse/src/lexer/unescape_error_reporting.rs

+17-2
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,26 @@ pub(crate) fn emit_unescape_error(
113113
} else {
114114
("", "if you meant to write a `str` literal, use double quotes")
115115
};
116-
116+
let mut escaped = String::with_capacity(lit.len());
117+
let mut chrs = lit.chars().peekable();
118+
while let Some(first) = chrs.next() {
119+
match (first, chrs.peek()) {
120+
('\\', Some('"')) => {
121+
escaped.push('\\');
122+
escaped.push('"');
123+
chrs.next();
124+
}
125+
('"', _) => {
126+
escaped.push('\\');
127+
escaped.push('"')
128+
}
129+
(c, _) => escaped.push(c),
130+
};
131+
}
117132
handler.span_suggestion(
118133
span_with_quotes,
119134
msg,
120-
format!("{}\"{}\"", prefix, lit),
135+
format!("{prefix}\"{escaped}\""),
121136
Applicability::MachineApplicable,
122137
);
123138
}

0 commit comments

Comments
 (0)