Migrate "expected identifier" diagnostics to diagnostic structs

This commit is contained in:
Xiretza 2022-09-04 10:14:00 +02:00
parent 21b5194a3a
commit 7507ee29fc
4 changed files with 170 additions and 43 deletions

View file

@ -4,8 +4,9 @@ use super::{
TokenExpectType, TokenType,
};
use crate::errors::{
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, InInTypo, IncorrectAwait,
IncorrectSemicolon, IncorrectUseOfAwait, UseEqInstead,
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, ExpectedIdentifier, InInTypo,
IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, SuggEscapeToUseAsIdentifier,
SuggRemoveComma, UseEqInstead,
};
use crate::lexer::UnmatchedBrace;
@ -23,7 +24,7 @@ use rustc_data_structures::fx::FxHashSet;
use rustc_errors::{
fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed};
use rustc_errors::{pluralize, struct_span_err, Diagnostic, ErrorGuaranteed, IntoDiagnostic};
use rustc_span::source_map::Spanned;
use rustc_span::symbol::{kw, sym, Ident};
use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
@ -285,10 +286,6 @@ impl<'a> Parser<'a> {
}
pub(super) fn expected_ident_found(&self) -> DiagnosticBuilder<'a, ErrorGuaranteed> {
let mut err = self.struct_span_err(
self.token.span,
&format!("expected identifier, found {}", super::token_descr(&self.token)),
);
let valid_follow = &[
TokenKind::Eq,
TokenKind::Colon,
@ -300,34 +297,33 @@ impl<'a> Parser<'a> {
TokenKind::CloseDelim(Delimiter::Brace),
TokenKind::CloseDelim(Delimiter::Parenthesis),
];
match self.token.ident() {
let suggest_raw = match self.token.ident() {
Some((ident, false))
if ident.is_raw_guess()
&& self.look_ahead(1, |t| valid_follow.contains(&t.kind)) =>
{
err.span_suggestion_verbose(
ident.span.shrink_to_lo(),
&format!("escape `{}` to use it as an identifier", ident.name),
"r#",
Applicability::MaybeIncorrect,
);
Some(SuggEscapeToUseAsIdentifier {
span: ident.span.shrink_to_lo(),
ident_name: ident.name.to_string(),
})
}
_ => {}
}
if let Some(token_descr) = super::token_descr_opt(&self.token) {
err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
} else {
err.span_label(self.token.span, "expected identifier");
_ => None,
};
let suggest_remove_comma =
if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
err.span_suggestion(
self.token.span,
"remove this comma",
"",
Applicability::MachineApplicable,
);
}
}
err
Some(SuggRemoveComma { span: self.token.span })
} else {
None
};
let err = ExpectedIdentifier {
span: self.token.span,
token_descr: super::token_descr_struct(&self.token),
suggest_raw,
suggest_remove_comma,
};
err.into_diagnostic(&self.sess.span_diagnostic)
}
pub(super) fn expected_one_of_not_found(

View file

@ -410,22 +410,44 @@ pub enum FollowedByType {
No,
}
fn token_descr_opt(token: &Token) -> Option<&'static str> {
Some(match token.kind {
_ if token.is_special_ident() => "reserved identifier",
_ if token.is_used_keyword() => "keyword",
_ if token.is_unused_keyword() => "reserved keyword",
token::DocComment(..) => "doc comment",
_ => return None,
})
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum TokenDescriptionKind {
ReservedIdentifier,
Keyword,
ReservedKeyword,
DocComment,
}
#[derive(Clone, PartialEq, Eq)]
pub struct TokenDescription {
pub kind: Option<TokenDescriptionKind>,
pub name: String,
}
pub(super) fn token_descr_struct(token: &Token) -> TokenDescription {
let kind = match token.kind {
_ if token.is_special_ident() => Some(TokenDescriptionKind::ReservedIdentifier),
_ if token.is_used_keyword() => Some(TokenDescriptionKind::Keyword),
_ if token.is_unused_keyword() => Some(TokenDescriptionKind::ReservedKeyword),
token::DocComment(..) => Some(TokenDescriptionKind::DocComment),
_ => None,
};
let name = pprust::token_to_string(token).to_string();
TokenDescription { kind, name }
}
pub(super) fn token_descr(token: &Token) -> String {
let token_str = pprust::token_to_string(token);
match token_descr_opt(token) {
Some(prefix) => format!("{} `{}`", prefix, token_str),
_ => format!("`{}`", token_str),
}
let TokenDescription { kind, name } = token_descr_struct(token);
let kind = kind.map(|kind| match kind {
TokenDescriptionKind::ReservedIdentifier => "reserved identifier",
TokenDescriptionKind::Keyword => "keyword",
TokenDescriptionKind::ReservedKeyword => "reserved keyword",
TokenDescriptionKind::DocComment => "doc comment",
});
if let Some(kind) = kind { format!("{} `{}`", kind, name) } else { format!("`{}`", name) }
}
impl<'a> Parser<'a> {