mirror of
https://github.com/rust-lang/rust.git
synced 2024-11-22 14:55:26 +00:00
Migrate "expected identifier" diagnostics to diagnostic structs
This commit is contained in:
parent
21b5194a3a
commit
7507ee29fc
@ -290,3 +290,19 @@ parser_inner_doc_comment_not_permitted = expected outer doc comment
|
|||||||
.suggestion = you might have meant to write a regular comment
|
.suggestion = you might have meant to write a regular comment
|
||||||
.label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item}
|
.label_does_not_annotate_this = the inner doc comment doesn't annotate this {$item}
|
||||||
.sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style
|
.sugg_change_inner_to_outer = to annotate the {$item}, change the doc comment from inner to outer style
|
||||||
|
|
||||||
|
parser_expected_identifier_found_reserved_identifier_str = expected identifier, found reserved identifier `{$token_str}`
|
||||||
|
parser_expected_identifier_found_keyword_str = expected identifier, found keyword `{$token_str}`
|
||||||
|
parser_expected_identifier_found_reserved_keyword_str = expected identifier, found reserved keyword `{$token_str}`
|
||||||
|
parser_expected_identifier_found_doc_comment_str = expected identifier, found doc comment `{$token_str}`
|
||||||
|
parser_expected_identifier_found_str = expected identifier, found `{$token_str}`
|
||||||
|
|
||||||
|
parser_expected_identifier_found_reserved_identifier = expected identifier, found reserved identifier
|
||||||
|
parser_expected_identifier_found_keyword = expected identifier, found keyword
|
||||||
|
parser_expected_identifier_found_reserved_keyword = expected identifier, found reserved keyword
|
||||||
|
parser_expected_identifier_found_doc_comment = expected identifier, found doc comment
|
||||||
|
parser_expected_identifier = expected identifier
|
||||||
|
|
||||||
|
parser_sugg_escape_to_use_as_identifier = escape `{$ident_name}` to use it as an identifier
|
||||||
|
|
||||||
|
parser_sugg_remove_comma = remove this comma
|
||||||
|
@ -1,9 +1,11 @@
|
|||||||
use rustc_errors::Applicability;
|
use rustc_errors::{fluent, AddToDiagnostic, Applicability, EmissionGuarantee, IntoDiagnostic};
|
||||||
use rustc_macros::{Diagnostic, Subdiagnostic};
|
use rustc_macros::{Diagnostic, Subdiagnostic};
|
||||||
use rustc_session::errors::ExprParenthesesNeeded;
|
use rustc_session::errors::ExprParenthesesNeeded;
|
||||||
use rustc_span::symbol::Ident;
|
use rustc_span::symbol::Ident;
|
||||||
use rustc_span::{Span, Symbol};
|
use rustc_span::{Span, Symbol};
|
||||||
|
|
||||||
|
use crate::parser::{TokenDescription, TokenDescriptionKind};
|
||||||
|
|
||||||
#[derive(Diagnostic)]
|
#[derive(Diagnostic)]
|
||||||
#[diag(parser::maybe_report_ambiguous_plus)]
|
#[diag(parser::maybe_report_ambiguous_plus)]
|
||||||
pub(crate) struct AmbiguousPlus {
|
pub(crate) struct AmbiguousPlus {
|
||||||
@ -870,3 +872,94 @@ pub(crate) struct InvalidMetaItem {
|
|||||||
pub span: Span,
|
pub span: Span,
|
||||||
pub token: String,
|
pub token: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[suggestion_verbose(
|
||||||
|
parser::sugg_escape_to_use_as_identifier,
|
||||||
|
applicability = "maybe-incorrect",
|
||||||
|
code = "r#"
|
||||||
|
)]
|
||||||
|
pub(crate) struct SuggEscapeToUseAsIdentifier {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
pub ident_name: String,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
#[suggestion(parser::sugg_remove_comma, applicability = "machine-applicable", code = "")]
|
||||||
|
pub(crate) struct SuggRemoveComma {
|
||||||
|
#[primary_span]
|
||||||
|
pub span: Span,
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Subdiagnostic)]
|
||||||
|
pub(crate) enum ExpectedIdentifierFound {
|
||||||
|
#[label(parser::expected_identifier_found_reserved_identifier)]
|
||||||
|
ReservedIdentifier(#[primary_span] Span),
|
||||||
|
#[label(parser::expected_identifier_found_keyword)]
|
||||||
|
Keyword(#[primary_span] Span),
|
||||||
|
#[label(parser::expected_identifier_found_reserved_keyword)]
|
||||||
|
ReservedKeyword(#[primary_span] Span),
|
||||||
|
#[label(parser::expected_identifier_found_doc_comment)]
|
||||||
|
DocComment(#[primary_span] Span),
|
||||||
|
#[label(parser::expected_identifier)]
|
||||||
|
Other(#[primary_span] Span),
|
||||||
|
}
|
||||||
|
|
||||||
|
impl ExpectedIdentifierFound {
|
||||||
|
pub fn new(token_descr_kind: Option<TokenDescriptionKind>, span: Span) -> Self {
|
||||||
|
(match token_descr_kind {
|
||||||
|
Some(TokenDescriptionKind::ReservedIdentifier) => {
|
||||||
|
ExpectedIdentifierFound::ReservedIdentifier
|
||||||
|
}
|
||||||
|
Some(TokenDescriptionKind::Keyword) => ExpectedIdentifierFound::Keyword,
|
||||||
|
Some(TokenDescriptionKind::ReservedKeyword) => ExpectedIdentifierFound::ReservedKeyword,
|
||||||
|
Some(TokenDescriptionKind::DocComment) => ExpectedIdentifierFound::DocComment,
|
||||||
|
None => ExpectedIdentifierFound::Other,
|
||||||
|
})(span)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub(crate) struct ExpectedIdentifier {
|
||||||
|
pub span: Span,
|
||||||
|
pub token_descr: TokenDescription,
|
||||||
|
pub suggest_raw: Option<SuggEscapeToUseAsIdentifier>,
|
||||||
|
pub suggest_remove_comma: Option<SuggRemoveComma>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
|
||||||
|
fn into_diagnostic(
|
||||||
|
self,
|
||||||
|
handler: &'a rustc_errors::Handler,
|
||||||
|
) -> rustc_errors::DiagnosticBuilder<'a, G> {
|
||||||
|
let mut diag = handler.struct_diagnostic(match self.token_descr.kind {
|
||||||
|
Some(TokenDescriptionKind::ReservedIdentifier) => {
|
||||||
|
fluent::parser::expected_identifier_found_reserved_identifier_str
|
||||||
|
}
|
||||||
|
Some(TokenDescriptionKind::Keyword) => {
|
||||||
|
fluent::parser::expected_identifier_found_keyword_str
|
||||||
|
}
|
||||||
|
Some(TokenDescriptionKind::ReservedKeyword) => {
|
||||||
|
fluent::parser::expected_identifier_found_reserved_keyword_str
|
||||||
|
}
|
||||||
|
Some(TokenDescriptionKind::DocComment) => {
|
||||||
|
fluent::parser::expected_identifier_found_doc_comment_str
|
||||||
|
}
|
||||||
|
None => fluent::parser::expected_identifier_found_str,
|
||||||
|
});
|
||||||
|
diag.set_span(self.span);
|
||||||
|
diag.set_arg("token_str", self.token_descr.name);
|
||||||
|
|
||||||
|
if let Some(sugg) = self.suggest_raw {
|
||||||
|
sugg.add_to_diagnostic(&mut diag);
|
||||||
|
}
|
||||||
|
|
||||||
|
ExpectedIdentifierFound::new(self.token_descr.kind, self.span).add_to_diagnostic(&mut diag);
|
||||||
|
|
||||||
|
if let Some(sugg) = self.suggest_remove_comma {
|
||||||
|
sugg.add_to_diagnostic(&mut diag);
|
||||||
|
}
|
||||||
|
|
||||||
|
diag
|
||||||
|
}
|
||||||
|
}
|
||||||
|
@ -4,8 +4,9 @@ use super::{
|
|||||||
TokenExpectType, TokenType,
|
TokenExpectType, TokenType,
|
||||||
};
|
};
|
||||||
use crate::errors::{
|
use crate::errors::{
|
||||||
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, InInTypo, IncorrectAwait,
|
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, ExpectedIdentifier, InInTypo,
|
||||||
IncorrectSemicolon, IncorrectUseOfAwait, UseEqInstead,
|
IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, SuggEscapeToUseAsIdentifier,
|
||||||
|
SuggRemoveComma, UseEqInstead,
|
||||||
};
|
};
|
||||||
|
|
||||||
use crate::lexer::UnmatchedBrace;
|
use crate::lexer::UnmatchedBrace;
|
||||||
@ -23,7 +24,7 @@ use rustc_data_structures::fx::FxHashSet;
|
|||||||
use rustc_errors::{
|
use rustc_errors::{
|
||||||
fluent, Applicability, DiagnosticBuilder, DiagnosticMessage, Handler, MultiSpan, PResult,
|
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::source_map::Spanned;
|
||||||
use rustc_span::symbol::{kw, sym, Ident};
|
use rustc_span::symbol::{kw, sym, Ident};
|
||||||
use rustc_span::{Span, SpanSnippetError, DUMMY_SP};
|
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> {
|
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 = &[
|
let valid_follow = &[
|
||||||
TokenKind::Eq,
|
TokenKind::Eq,
|
||||||
TokenKind::Colon,
|
TokenKind::Colon,
|
||||||
@ -300,34 +297,33 @@ impl<'a> Parser<'a> {
|
|||||||
TokenKind::CloseDelim(Delimiter::Brace),
|
TokenKind::CloseDelim(Delimiter::Brace),
|
||||||
TokenKind::CloseDelim(Delimiter::Parenthesis),
|
TokenKind::CloseDelim(Delimiter::Parenthesis),
|
||||||
];
|
];
|
||||||
match self.token.ident() {
|
let suggest_raw = match self.token.ident() {
|
||||||
Some((ident, false))
|
Some((ident, false))
|
||||||
if ident.is_raw_guess()
|
if ident.is_raw_guess()
|
||||||
&& self.look_ahead(1, |t| valid_follow.contains(&t.kind)) =>
|
&& self.look_ahead(1, |t| valid_follow.contains(&t.kind)) =>
|
||||||
{
|
{
|
||||||
err.span_suggestion_verbose(
|
Some(SuggEscapeToUseAsIdentifier {
|
||||||
ident.span.shrink_to_lo(),
|
span: ident.span.shrink_to_lo(),
|
||||||
&format!("escape `{}` to use it as an identifier", ident.name),
|
ident_name: ident.name.to_string(),
|
||||||
"r#",
|
})
|
||||||
Applicability::MaybeIncorrect,
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => None,
|
||||||
}
|
};
|
||||||
if let Some(token_descr) = super::token_descr_opt(&self.token) {
|
|
||||||
err.span_label(self.token.span, format!("expected identifier, found {}", token_descr));
|
let suggest_remove_comma =
|
||||||
} else {
|
|
||||||
err.span_label(self.token.span, "expected identifier");
|
|
||||||
if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
|
if self.token == token::Comma && self.look_ahead(1, |t| t.is_ident()) {
|
||||||
err.span_suggestion(
|
Some(SuggRemoveComma { span: self.token.span })
|
||||||
self.token.span,
|
} else {
|
||||||
"remove this comma",
|
None
|
||||||
"",
|
};
|
||||||
Applicability::MachineApplicable,
|
|
||||||
);
|
let err = ExpectedIdentifier {
|
||||||
}
|
span: self.token.span,
|
||||||
}
|
token_descr: super::token_descr_struct(&self.token),
|
||||||
err
|
suggest_raw,
|
||||||
|
suggest_remove_comma,
|
||||||
|
};
|
||||||
|
err.into_diagnostic(&self.sess.span_diagnostic)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn expected_one_of_not_found(
|
pub(super) fn expected_one_of_not_found(
|
||||||
|
@ -410,22 +410,44 @@ pub enum FollowedByType {
|
|||||||
No,
|
No,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn token_descr_opt(token: &Token) -> Option<&'static str> {
|
#[derive(Clone, Copy, PartialEq, Eq)]
|
||||||
Some(match token.kind {
|
pub enum TokenDescriptionKind {
|
||||||
_ if token.is_special_ident() => "reserved identifier",
|
ReservedIdentifier,
|
||||||
_ if token.is_used_keyword() => "keyword",
|
Keyword,
|
||||||
_ if token.is_unused_keyword() => "reserved keyword",
|
ReservedKeyword,
|
||||||
token::DocComment(..) => "doc comment",
|
DocComment,
|
||||||
_ => return None,
|
}
|
||||||
})
|
|
||||||
|
#[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 {
|
pub(super) fn token_descr(token: &Token) -> String {
|
||||||
let token_str = pprust::token_to_string(token);
|
let TokenDescription { kind, name } = token_descr_struct(token);
|
||||||
match token_descr_opt(token) {
|
|
||||||
Some(prefix) => format!("{} `{}`", prefix, token_str),
|
let kind = kind.map(|kind| match kind {
|
||||||
_ => format!("`{}`", token_str),
|
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> {
|
impl<'a> Parser<'a> {
|
||||||
|
Loading…
Reference in New Issue
Block a user