Migrate "expected identifier" diagnostics to diagnostic structs
This commit is contained in:
parent
21b5194a3a
commit
7507ee29fc
4 changed files with 170 additions and 43 deletions
|
@ -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(
|
||||
|
|
|
@ -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> {
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue