Properly escape quotes when suggesting switching between char/string literals

This commit is contained in:
clubby789 2022-10-22 02:37:15 +01:00
parent 0940040c04
commit ed40d46159
2 changed files with 38 additions and 4 deletions

View File

@ -2272,6 +2272,25 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str) struct_span_err!(self.tcx.sess, span, E0580, "{}", failure_str)
} }
FailureCode::Error0308(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); let mut err = struct_span_err!(self.tcx.sess, span, E0308, "{}", failure_str);
if let Some((expected, found)) = trace.values.ty() { if let Some((expected, found)) = trace.values.ty() {
match (expected.kind(), found.kind()) { match (expected.kind(), found.kind()) {
@ -2293,7 +2312,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.span_suggestion( err.span_suggestion(
span, span,
"if you meant to write a `char` literal, use single quotes", "if you meant to write a `char` literal, use single quotes",
format!("'{}'", code), format!("'{}'", escape_literal(code)),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} }
@ -2308,7 +2327,7 @@ impl<'tcx> TypeErrCtxt<'_, 'tcx> {
err.span_suggestion( err.span_suggestion(
span, span,
"if you meant to write a `str` literal, use double quotes", "if you meant to write a `str` literal, use double quotes",
format!("\"{}\"", code), format!("\"{}\"", escape_literal(code)),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} }

View File

@ -113,11 +113,26 @@ pub(crate) fn emit_unescape_error(
} else { } else {
("", "if you meant to write a `str` literal, use double quotes") ("", "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( handler.span_suggestion(
span_with_quotes, span_with_quotes,
msg, msg,
format!("{}\"{}\"", prefix, lit), format!("{prefix}\"{escaped}\""),
Applicability::MachineApplicable, Applicability::MachineApplicable,
); );
} }