Remove LitError::LexerError.

`cook_lexer_literal` can emit an error about an invalid int literal but
then return a non-`Err` token. And then `integer_lit` has to account for
this to avoid printing a redundant error message.

This commit changes `cook_lexer_literal` to return `Err` in that case.
Then `integer_lit` doesn't need the special case, and
`LitError::LexerError` can be removed.
This commit is contained in:
Nicholas Nethercote 2024-02-14 19:09:25 +11:00
parent ee9c7c940c
commit 8b35f8e41e
3 changed files with 18 additions and 26 deletions

View File

@ -31,7 +31,6 @@ pub fn escape_byte_str_symbol(bytes: &[u8]) -> Symbol {
#[derive(Debug)]
pub enum LitError {
LexerError,
InvalidSuffix,
InvalidIntSuffix,
InvalidFloatSuffix,
@ -324,11 +323,7 @@ fn integer_lit(symbol: Symbol, suffix: Option<Symbol>) -> Result<LitKind, LitErr
};
let s = &s[if base != 10 { 2 } else { 0 }..];
u128::from_str_radix(s, base).map(|i| LitKind::Int(i.into(), ty)).map_err(|_| {
// Small bases are lexed as if they were base 10, e.g, the string
// might be `0b10201`. This will cause the conversion above to fail,
// but these kinds of errors are already reported by the lexer.
let from_lexer = base < 10 && s.chars().any(|c| c.to_digit(10).is_some_and(|d| d >= base));
if from_lexer { LitError::LexerError } else { LitError::IntTooLarge(base) }
})
u128::from_str_radix(s, base)
.map(|i| LitKind::Int(i.into(), ty))
.map_err(|_| LitError::IntTooLarge(base))
}

View File

@ -16,7 +16,7 @@ use rustc_session::lint::builtin::{
};
use rustc_session::lint::BuiltinLintDiagnostics;
use rustc_session::parse::ParseSess;
use rustc_span::symbol::{sym, Symbol};
use rustc_span::symbol::Symbol;
use rustc_span::{edition::Edition, BytePos, Pos, Span};
mod diagnostics;
@ -478,26 +478,26 @@ impl<'sess, 'src> StringReader<'sess, 'src> {
}
}
rustc_lexer::LiteralKind::Int { base, empty_int } => {
let mut kind = token::Integer;
if empty_int {
let span = self.mk_sp(start, end);
self.dcx().emit_err(errors::NoDigitsLiteral { span });
(token::Integer, sym::integer(0))
} else {
if matches!(base, Base::Binary | Base::Octal) {
let base = base as u32;
let s = self.str_from_to(start + BytePos(2), end);
for (idx, c) in s.char_indices() {
let span = self.mk_sp(
start + BytePos::from_usize(2 + idx),
start + BytePos::from_usize(2 + idx + c.len_utf8()),
);
if c != '_' && c.to_digit(base).is_none() {
self.dcx().emit_err(errors::InvalidDigitLiteral { span, base });
}
kind = token::Err;
} else if matches!(base, Base::Binary | Base::Octal) {
let base = base as u32;
let s = self.str_from_to(start + BytePos(2), end);
for (idx, c) in s.char_indices() {
let span = self.mk_sp(
start + BytePos::from_usize(2 + idx),
start + BytePos::from_usize(2 + idx + c.len_utf8()),
);
if c != '_' && c.to_digit(base).is_none() {
self.dcx().emit_err(errors::InvalidDigitLiteral { span, base });
kind = token::Err;
}
}
(token::Integer, self.symbol_from_to(start, end))
}
(kind, self.symbol_from_to(start, end))
}
rustc_lexer::LiteralKind::Float { base, empty_exponent } => {
if empty_exponent {

View File

@ -375,9 +375,6 @@ pub fn report_lit_error(sess: &ParseSess, err: LitError, lit: token::Lit, span:
let token::Lit { kind, symbol, suffix, .. } = lit;
let dcx = &sess.dcx;
match err {
// `LexerError` is an error, but it was already reported
// by lexer, so here we don't report it the second time.
LitError::LexerError => {}
LitError::InvalidSuffix => {
if let Some(suffix) = suffix {
dcx.emit_err(InvalidLiteralSuffix { span, kind: kind.descr(), suffix });