Make emit_unescape_error
return Option<ErrorGuaranteed>
.
And use the result in `cook_common` to decide whether to return an error token.
This commit is contained in:
parent
a513bb20c3
commit
332c57723a
2 changed files with 34 additions and 40 deletions
|
@ -691,7 +691,7 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
|
||||||
|
|
||||||
fn cook_common(
|
fn cook_common(
|
||||||
&self,
|
&self,
|
||||||
kind: token::LitKind,
|
mut kind: token::LitKind,
|
||||||
mode: Mode,
|
mode: Mode,
|
||||||
start: BytePos,
|
start: BytePos,
|
||||||
end: BytePos,
|
end: BytePos,
|
||||||
|
@ -699,7 +699,6 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
|
||||||
postfix_len: u32,
|
postfix_len: u32,
|
||||||
unescape: fn(&str, Mode, &mut dyn FnMut(Range<usize>, Result<(), EscapeError>)),
|
unescape: fn(&str, Mode, &mut dyn FnMut(Range<usize>, Result<(), EscapeError>)),
|
||||||
) -> (token::LitKind, Symbol) {
|
) -> (token::LitKind, Symbol) {
|
||||||
let mut has_fatal_err = false;
|
|
||||||
let content_start = start + BytePos(prefix_len);
|
let content_start = start + BytePos(prefix_len);
|
||||||
let content_end = end - BytePos(postfix_len);
|
let content_end = end - BytePos(postfix_len);
|
||||||
let lit_content = self.str_from_to(content_start, content_end);
|
let lit_content = self.str_from_to(content_start, content_end);
|
||||||
|
@ -711,10 +710,8 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
|
||||||
let lo = content_start + BytePos(start);
|
let lo = content_start + BytePos(start);
|
||||||
let hi = lo + BytePos(end - start);
|
let hi = lo + BytePos(end - start);
|
||||||
let span = self.mk_sp(lo, hi);
|
let span = self.mk_sp(lo, hi);
|
||||||
if err.is_fatal() {
|
let is_fatal = err.is_fatal();
|
||||||
has_fatal_err = true;
|
if let Some(_guar) = emit_unescape_error(
|
||||||
}
|
|
||||||
emit_unescape_error(
|
|
||||||
self.dcx(),
|
self.dcx(),
|
||||||
lit_content,
|
lit_content,
|
||||||
span_with_quotes,
|
span_with_quotes,
|
||||||
|
@ -722,13 +719,16 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
|
||||||
mode,
|
mode,
|
||||||
range,
|
range,
|
||||||
err,
|
err,
|
||||||
);
|
) {
|
||||||
|
assert!(is_fatal);
|
||||||
|
kind = token::Err;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// We normally exclude the quotes for the symbol, but for errors we
|
// We normally exclude the quotes for the symbol, but for errors we
|
||||||
// include it because it results in clearer error messages.
|
// include it because it results in clearer error messages.
|
||||||
if !has_fatal_err {
|
if kind != token::Err {
|
||||||
(kind, Symbol::intern(lit_content))
|
(kind, Symbol::intern(lit_content))
|
||||||
} else {
|
} else {
|
||||||
(token::Err, self.symbol_from_to(start, end))
|
(token::Err, self.symbol_from_to(start, end))
|
||||||
|
|
|
@ -3,7 +3,7 @@
|
||||||
use std::iter::once;
|
use std::iter::once;
|
||||||
use std::ops::Range;
|
use std::ops::Range;
|
||||||
|
|
||||||
use rustc_errors::{Applicability, DiagCtxt};
|
use rustc_errors::{Applicability, DiagCtxt, ErrorGuaranteed};
|
||||||
use rustc_lexer::unescape::{EscapeError, Mode};
|
use rustc_lexer::unescape::{EscapeError, Mode};
|
||||||
use rustc_span::{BytePos, Span};
|
use rustc_span::{BytePos, Span};
|
||||||
|
|
||||||
|
@ -21,7 +21,7 @@ pub(crate) fn emit_unescape_error(
|
||||||
// range of the error inside `lit`
|
// range of the error inside `lit`
|
||||||
range: Range<usize>,
|
range: Range<usize>,
|
||||||
error: EscapeError,
|
error: EscapeError,
|
||||||
) {
|
) -> Option<ErrorGuaranteed> {
|
||||||
debug!(
|
debug!(
|
||||||
"emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}",
|
"emit_unescape_error: {:?}, {:?}, {:?}, {:?}, {:?}",
|
||||||
lit, full_lit_span, mode, range, error
|
lit, full_lit_span, mode, range, error
|
||||||
|
@ -31,12 +31,12 @@ pub(crate) fn emit_unescape_error(
|
||||||
let span = err_span.with_lo(err_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)
|
(c, span)
|
||||||
};
|
};
|
||||||
match error {
|
Some(match error {
|
||||||
EscapeError::LoneSurrogateUnicodeEscape => {
|
EscapeError::LoneSurrogateUnicodeEscape => {
|
||||||
dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: true });
|
dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: true })
|
||||||
}
|
}
|
||||||
EscapeError::OutOfRangeUnicodeEscape => {
|
EscapeError::OutOfRangeUnicodeEscape => {
|
||||||
dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: false });
|
dcx.emit_err(UnescapeError::InvalidUnicodeEscape { span: err_span, surrogate: false })
|
||||||
}
|
}
|
||||||
EscapeError::MoreThanOneChar => {
|
EscapeError::MoreThanOneChar => {
|
||||||
use unicode_normalization::{char::is_combining_mark, UnicodeNormalization};
|
use unicode_normalization::{char::is_combining_mark, UnicodeNormalization};
|
||||||
|
@ -106,7 +106,7 @@ pub(crate) fn emit_unescape_error(
|
||||||
span: full_lit_span,
|
span: full_lit_span,
|
||||||
note,
|
note,
|
||||||
suggestion: sugg,
|
suggestion: sugg,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
EscapeError::EscapeOnlyChar => {
|
EscapeError::EscapeOnlyChar => {
|
||||||
let (c, char_span) = last_char();
|
let (c, char_span) = last_char();
|
||||||
|
@ -116,15 +116,15 @@ pub(crate) fn emit_unescape_error(
|
||||||
escaped_sugg: c.escape_default().to_string(),
|
escaped_sugg: c.escape_default().to_string(),
|
||||||
escaped_msg: escaped_char(c),
|
escaped_msg: escaped_char(c),
|
||||||
byte: mode == Mode::Byte,
|
byte: mode == Mode::Byte,
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
EscapeError::BareCarriageReturn => {
|
EscapeError::BareCarriageReturn => {
|
||||||
let double_quotes = mode.in_double_quotes();
|
let double_quotes = mode.in_double_quotes();
|
||||||
dcx.emit_err(UnescapeError::BareCr { span: err_span, double_quotes });
|
dcx.emit_err(UnescapeError::BareCr { span: err_span, double_quotes })
|
||||||
}
|
}
|
||||||
EscapeError::BareCarriageReturnInRawString => {
|
EscapeError::BareCarriageReturnInRawString => {
|
||||||
assert!(mode.in_double_quotes());
|
assert!(mode.in_double_quotes());
|
||||||
dcx.emit_err(UnescapeError::BareCrRawString(err_span));
|
dcx.emit_err(UnescapeError::BareCrRawString(err_span))
|
||||||
}
|
}
|
||||||
EscapeError::InvalidEscape => {
|
EscapeError::InvalidEscape => {
|
||||||
let (c, span) = last_char();
|
let (c, span) = last_char();
|
||||||
|
@ -161,16 +161,14 @@ pub(crate) fn emit_unescape_error(
|
||||||
<https://doc.rust-lang.org/reference/tokens.html#literals>",
|
<https://doc.rust-lang.org/reference/tokens.html#literals>",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
diag.emit();
|
diag.emit()
|
||||||
}
|
|
||||||
EscapeError::TooShortHexEscape => {
|
|
||||||
dcx.emit_err(UnescapeError::TooShortHexEscape(err_span));
|
|
||||||
}
|
}
|
||||||
|
EscapeError::TooShortHexEscape => dcx.emit_err(UnescapeError::TooShortHexEscape(err_span)),
|
||||||
EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => {
|
EscapeError::InvalidCharInHexEscape | EscapeError::InvalidCharInUnicodeEscape => {
|
||||||
let (c, span) = last_char();
|
let (c, span) = last_char();
|
||||||
let is_hex = error == EscapeError::InvalidCharInHexEscape;
|
let is_hex = error == EscapeError::InvalidCharInHexEscape;
|
||||||
let ch = escaped_char(c);
|
let ch = escaped_char(c);
|
||||||
dcx.emit_err(UnescapeError::InvalidCharInEscape { span, is_hex, ch });
|
dcx.emit_err(UnescapeError::InvalidCharInEscape { span, is_hex, ch })
|
||||||
}
|
}
|
||||||
EscapeError::NonAsciiCharInByte => {
|
EscapeError::NonAsciiCharInByte => {
|
||||||
let (c, span) = last_char();
|
let (c, span) = last_char();
|
||||||
|
@ -213,23 +211,23 @@ pub(crate) fn emit_unescape_error(
|
||||||
Applicability::MaybeIncorrect,
|
Applicability::MaybeIncorrect,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
err.emit();
|
err.emit()
|
||||||
}
|
}
|
||||||
EscapeError::OutOfRangeHexEscape => {
|
EscapeError::OutOfRangeHexEscape => {
|
||||||
dcx.emit_err(UnescapeError::OutOfRangeHexEscape(err_span));
|
dcx.emit_err(UnescapeError::OutOfRangeHexEscape(err_span))
|
||||||
}
|
}
|
||||||
EscapeError::LeadingUnderscoreUnicodeEscape => {
|
EscapeError::LeadingUnderscoreUnicodeEscape => {
|
||||||
let (c, span) = last_char();
|
let (c, span) = last_char();
|
||||||
dcx.emit_err(UnescapeError::LeadingUnderscoreUnicodeEscape {
|
dcx.emit_err(UnescapeError::LeadingUnderscoreUnicodeEscape {
|
||||||
span,
|
span,
|
||||||
ch: escaped_char(c),
|
ch: escaped_char(c),
|
||||||
});
|
})
|
||||||
}
|
}
|
||||||
EscapeError::OverlongUnicodeEscape => {
|
EscapeError::OverlongUnicodeEscape => {
|
||||||
dcx.emit_err(UnescapeError::OverlongUnicodeEscape(err_span));
|
dcx.emit_err(UnescapeError::OverlongUnicodeEscape(err_span))
|
||||||
}
|
}
|
||||||
EscapeError::UnclosedUnicodeEscape => {
|
EscapeError::UnclosedUnicodeEscape => {
|
||||||
dcx.emit_err(UnescapeError::UnclosedUnicodeEscape(err_span, err_span.shrink_to_hi()));
|
dcx.emit_err(UnescapeError::UnclosedUnicodeEscape(err_span, err_span.shrink_to_hi()))
|
||||||
}
|
}
|
||||||
EscapeError::NoBraceInUnicodeEscape => {
|
EscapeError::NoBraceInUnicodeEscape => {
|
||||||
let mut suggestion = "\\u{".to_owned();
|
let mut suggestion = "\\u{".to_owned();
|
||||||
|
@ -248,23 +246,17 @@ pub(crate) fn emit_unescape_error(
|
||||||
} else {
|
} else {
|
||||||
(Some(err_span), NoBraceUnicodeSub::Help)
|
(Some(err_span), NoBraceUnicodeSub::Help)
|
||||||
};
|
};
|
||||||
dcx.emit_err(UnescapeError::NoBraceInUnicodeEscape { span: err_span, label, sub });
|
dcx.emit_err(UnescapeError::NoBraceInUnicodeEscape { span: err_span, label, sub })
|
||||||
}
|
}
|
||||||
EscapeError::UnicodeEscapeInByte => {
|
EscapeError::UnicodeEscapeInByte => {
|
||||||
dcx.emit_err(UnescapeError::UnicodeEscapeInByte(err_span));
|
dcx.emit_err(UnescapeError::UnicodeEscapeInByte(err_span))
|
||||||
}
|
}
|
||||||
EscapeError::EmptyUnicodeEscape => {
|
EscapeError::EmptyUnicodeEscape => {
|
||||||
dcx.emit_err(UnescapeError::EmptyUnicodeEscape(err_span));
|
dcx.emit_err(UnescapeError::EmptyUnicodeEscape(err_span))
|
||||||
}
|
|
||||||
EscapeError::ZeroChars => {
|
|
||||||
dcx.emit_err(UnescapeError::ZeroChars(err_span));
|
|
||||||
}
|
|
||||||
EscapeError::LoneSlash => {
|
|
||||||
dcx.emit_err(UnescapeError::LoneSlash(err_span));
|
|
||||||
}
|
|
||||||
EscapeError::NulInCStr => {
|
|
||||||
dcx.emit_err(UnescapeError::NulInCStr { span: err_span });
|
|
||||||
}
|
}
|
||||||
|
EscapeError::ZeroChars => dcx.emit_err(UnescapeError::ZeroChars(err_span)),
|
||||||
|
EscapeError::LoneSlash => dcx.emit_err(UnescapeError::LoneSlash(err_span)),
|
||||||
|
EscapeError::NulInCStr => dcx.emit_err(UnescapeError::NulInCStr { span: err_span }),
|
||||||
EscapeError::UnskippedWhitespaceWarning => {
|
EscapeError::UnskippedWhitespaceWarning => {
|
||||||
let (c, char_span) = last_char();
|
let (c, char_span) = last_char();
|
||||||
dcx.emit_warn(UnescapeError::UnskippedWhitespace {
|
dcx.emit_warn(UnescapeError::UnskippedWhitespace {
|
||||||
|
@ -272,11 +264,13 @@ pub(crate) fn emit_unescape_error(
|
||||||
ch: escaped_char(c),
|
ch: escaped_char(c),
|
||||||
char_span,
|
char_span,
|
||||||
});
|
});
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
EscapeError::MultipleSkippedLinesWarning => {
|
EscapeError::MultipleSkippedLinesWarning => {
|
||||||
dcx.emit_warn(UnescapeError::MultipleSkippedLinesWarning(err_span));
|
dcx.emit_warn(UnescapeError::MultipleSkippedLinesWarning(err_span));
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
}
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Pushes a character to a message string for error reporting
|
/// Pushes a character to a message string for error reporting
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue