diff --git a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs index b659c40b233..2b4c2e3c250 100644 --- a/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs +++ b/compiler/rustc_parse/src/lexer/unescape_error_reporting.rs @@ -11,12 +11,12 @@ pub(crate) fn emit_unescape_error( handler: &Handler, - // interior part of the literal, without quotes + // interior part of the literal, between quotes lit: &str, - // full span of the literal, including quotes - span_with_quotes: Span, - // interior span of the literal, without quotes - span: Span, + // full span of the literal, including quotes and any prefix + full_lit_span: Span, + // span of the error part of the literal + err_span: Span, mode: Mode, // range of the error inside `lit` range: Range, @@ -24,19 +24,21 @@ pub(crate) fn emit_unescape_error( ) { debug!( "emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}", - lit, span_with_quotes, mode, range, error + lit, full_lit_span, mode, range, error ); let last_char = || { let c = lit[range.clone()].chars().next_back().unwrap(); - let span = span.with_lo(span.hi() - BytePos(c.len_utf8() as u32)); + let span = err_span.with_lo(err_span.hi() - BytePos(c.len_utf8() as u32)); (c, span) }; match error { EscapeError::LoneSurrogateUnicodeEscape => { - handler.emit_err(UnescapeError::InvalidUnicodeEscape { span, surrogate: true }); + handler + .emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: true }); } EscapeError::OutOfRangeUnicodeEscape => { - handler.emit_err(UnescapeError::InvalidUnicodeEscape { span, surrogate: false }); + handler + .emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: false }); } EscapeError::MoreThanOneChar => { use unicode_normalization::{char::is_combining_mark, UnicodeNormalization}; @@ -49,12 +51,16 @@ pub(crate) fn emit_unescape_error( let normalized = lit.nfc().to_string(); if normalized.chars().count() == 1 { let ch = normalized.chars().next().unwrap().escape_default().to_string(); - sugg = Some(MoreThanOneCharSugg::NormalizedForm { span, ch, normalized }); + sugg = Some(MoreThanOneCharSugg::NormalizedForm { + span: err_span, + ch, + normalized, + }); } let escaped_marks = rest.iter().map(|c| c.escape_default().to_string()).collect::>(); note = Some(MoreThanOneCharNote::AllCombining { - span, + span: err_span, chr: format!("{first}"), len: escaped_marks.len(), escaped_marks: escaped_marks.join(""), @@ -69,10 +75,12 @@ pub(crate) fn emit_unescape_error( .collect(); if let &[ch] = printable.as_slice() { - sugg = - Some(MoreThanOneCharSugg::RemoveNonPrinting { span, ch: ch.to_string() }); + sugg = Some(MoreThanOneCharSugg::RemoveNonPrinting { + span: err_span, + ch: ch.to_string(), + }); note = Some(MoreThanOneCharNote::NonPrinting { - span, + span: err_span, escaped: lit.escape_default().to_string(), }); } @@ -91,13 +99,13 @@ pub(crate) fn emit_unescape_error( } let sugg = format!("{prefix}\"{escaped}\""); MoreThanOneCharSugg::Quotes { - span: span_with_quotes, + span: full_lit_span, is_byte: mode == Mode::Byte, sugg, } }); handler.emit_err(UnescapeError::MoreThanOneChar { - span: span_with_quotes, + span: full_lit_span, note, suggestion: sugg, }); @@ -105,7 +113,7 @@ pub(crate) fn emit_unescape_error( EscapeError::EscapeOnlyChar => { let (c, char_span) = last_char(); handler.emit_err(UnescapeError::EscapeOnlyChar { - span, + span: err_span, char_span, escaped_sugg: c.escape_default().to_string(), escaped_msg: escaped_char(c), @@ -114,11 +122,11 @@ pub(crate) fn emit_unescape_error( } EscapeError::BareCarriageReturn => { let double_quotes = mode.in_double_quotes(); - handler.emit_err(UnescapeError::BareCr { span, double_quotes }); + handler.emit_err(UnescapeError::BareCr { span: err_span, double_quotes }); } EscapeError::BareCarriageReturnInRawString => { assert!(mode.in_double_quotes()); - handler.emit_err(UnescapeError::BareCrRawString(span)); + handler.emit_err(UnescapeError::BareCrRawString(err_span)); } EscapeError::InvalidEscape => { let (c, span) = last_char(); @@ -143,7 +151,7 @@ pub(crate) fn emit_unescape_error( } else { if mode == Mode::Str || mode == Mode::Char { diag.span_suggestion( - span_with_quotes, + full_lit_span, "if you meant to write a literal backslash (perhaps escaping in a regular expression), consider a raw string literal", format!("r\"{lit}\""), Applicability::MaybeIncorrect, @@ -158,7 +166,7 @@ pub(crate) fn emit_unescape_error( diag.emit(); } EscapeError::TooShortHexEscape => { - handler.emit_err(UnescapeError::TooShortHexEscape(span)); + handler.emit_err(UnescapeError::TooShortHexEscape(err_span)); } EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => { let (c, span) = last_char(); @@ -210,7 +218,7 @@ pub(crate) fn emit_unescape_error( err.emit(); } EscapeError::OutOfRangeHexEscape => { - handler.emit_err(UnescapeError::OutOfRangeHexEscape(span)); + handler.emit_err(UnescapeError::OutOfRangeHexEscape(err_span)); } EscapeError::LeadingUnderscoreUnicodeEscape => { let (c, span) = last_char(); @@ -220,10 +228,11 @@ pub(crate) fn emit_unescape_error( }); } EscapeError::OverlongUnicodeEscape => { - handler.emit_err(UnescapeError::OverlongUnicodeEscape(span)); + handler.emit_err(UnescapeError::OverlongUnicodeEscape(err_span)); } EscapeError::UnclosedUnicodeEscape => { - handler.emit_err(UnescapeError::UnclosedUnicodeEscape(span, span.shrink_to_hi())); + handler + .emit_err(UnescapeError::UnclosedUnicodeEscape(err_span, err_span.shrink_to_hi())); } EscapeError::NoBraceInUnicodeEscape => { let mut suggestion = "\\u{".to_owned(); @@ -238,34 +247,34 @@ pub(crate) fn emit_unescape_error( let (label, sub) = if suggestion_len > 0 { suggestion.push('}'); let hi = char_span.lo() + BytePos(suggestion_len as u32); - (None, NoBraceUnicodeSub::Suggestion { span: span.with_hi(hi), suggestion }) + (None, NoBraceUnicodeSub::Suggestion { span: err_span.with_hi(hi), suggestion }) } else { - (Some(span), NoBraceUnicodeSub::Help) + (Some(err_span), NoBraceUnicodeSub::Help) }; - handler.emit_err(UnescapeError::NoBraceInUnicodeEscape { span, label, sub }); + handler.emit_err(UnescapeError::NoBraceInUnicodeEscape { span: err_span, label, sub }); } EscapeError::UnicodeEscapeInByte => { - handler.emit_err(UnescapeError::UnicodeEscapeInByte(span)); + handler.emit_err(UnescapeError::UnicodeEscapeInByte(err_span)); } EscapeError::EmptyUnicodeEscape => { - handler.emit_err(UnescapeError::EmptyUnicodeEscape(span)); + handler.emit_err(UnescapeError::EmptyUnicodeEscape(err_span)); } EscapeError::ZeroChars => { - handler.emit_err(UnescapeError::ZeroChars(span)); + handler.emit_err(UnescapeError::ZeroChars(err_span)); } EscapeError::LoneSlash => { - handler.emit_err(UnescapeError::LoneSlash(span)); + handler.emit_err(UnescapeError::LoneSlash(err_span)); } EscapeError::UnskippedWhitespaceWarning => { let (c, char_span) = last_char(); handler.emit_warning(UnescapeError::UnskippedWhitespace { - span, + span: err_span, ch: escaped_char(c), char_span, }); } EscapeError::MultipleSkippedLinesWarning => { - handler.emit_warning(UnescapeError::MultipleSkippedLinesWarning(span)); + handler.emit_warning(UnescapeError::MultipleSkippedLinesWarning(err_span)); } } }