Migrate "expected semicolon" diagnostics to diagnostic structs

This commit is contained in:
Xiretza 2022-09-04 20:12:00 +02:00
parent 7507ee29fc
commit ba10f2c0f2
3 changed files with 82 additions and 16 deletions

View File

@ -306,3 +306,13 @@ 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
parser_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token_str}`
parser_expected_semi_found_keyword_str = expected `;`, found keyword `{$token_str}`
parser_expected_semi_found_reserved_keyword_str = expected `;`, found reserved keyword `{$token_str}`
parser_expected_semi_found_doc_comment_str = expected `;`, found doc comment `{$token_str}`
parser_expected_semi_found_str = expected `;`, found `{$token_str}`
parser_sugg_change_this_to_semi = change this to `;`
parser_sugg_add_semi = add `;` here
parser_label_unexpected_token = unexpected token

View File

@ -963,3 +963,54 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
diag
}
}
pub(crate) struct ExpectedSemi {
pub span: Span,
pub token_descr: TokenDescription,
pub unexpected_token_label: Option<Span>,
pub sugg: ExpectedSemiSugg,
}
impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
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_semi_found_reserved_identifier_str
}
Some(TokenDescriptionKind::Keyword) => fluent::parser::expected_semi_found_keyword_str,
Some(TokenDescriptionKind::ReservedKeyword) => {
fluent::parser::expected_semi_found_reserved_keyword_str
}
Some(TokenDescriptionKind::DocComment) => {
fluent::parser::expected_semi_found_doc_comment_str
}
None => fluent::parser::expected_semi_found_str,
});
diag.set_span(self.span);
diag.set_arg("token_str", self.token_descr.name);
if let Some(unexpected_token_label) = self.unexpected_token_label {
diag.span_label(unexpected_token_label, fluent::parser::label_unexpected_token);
}
self.sugg.add_to_diagnostic(&mut diag);
diag
}
}
#[derive(Subdiagnostic)]
pub(crate) enum ExpectedSemiSugg {
#[suggestion(
parser::sugg_change_this_to_semi,
code = ";",
applicability = "machine-applicable"
)]
ChangeToSemi(#[primary_span] Span),
#[suggestion_short(parser::sugg_add_semi, code = ";", applicability = "machine-applicable")]
AddSemi(#[primary_span] Span),
}

View File

@ -4,9 +4,9 @@ use super::{
TokenExpectType, TokenType,
};
use crate::errors::{
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, ExpectedIdentifier, InInTypo,
IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, SuggEscapeToUseAsIdentifier,
SuggRemoveComma, UseEqInstead,
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, ExpectedIdentifier, ExpectedSemi,
ExpectedSemiSugg, InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait,
SuggEscapeToUseAsIdentifier, SuggRemoveComma, UseEqInstead,
};
use crate::lexer::UnmatchedBrace;
@ -388,8 +388,8 @@ impl<'a> Parser<'a> {
expected.dedup();
let sm = self.sess.source_map();
let msg = format!("expected `;`, found {}", super::token_descr(&self.token));
let appl = Applicability::MachineApplicable;
// Special-case "expected `;`" errors
if expected.contains(&TokenType::Token(token::Semi)) {
if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP {
// Likely inside a macro, can't provide meaningful suggestions.
@ -417,11 +417,13 @@ impl<'a> Parser<'a> {
//
// let x = 32:
// let y = 42;
self.sess.emit_err(ExpectedSemi {
span: self.token.span,
token_descr: super::token_descr_struct(&self.token),
unexpected_token_label: None,
sugg: ExpectedSemiSugg::ChangeToSemi(self.token.span),
});
self.bump();
let sp = self.prev_token.span;
self.struct_span_err(sp, &msg)
.span_suggestion_short(sp, "change this to `;`", ";", appl)
.emit();
return Ok(true);
} else if self.look_ahead(0, |t| {
t == &token::CloseDelim(Delimiter::Brace)
@ -439,11 +441,13 @@ impl<'a> Parser<'a> {
//
// let x = 32
// let y = 42;
let sp = self.prev_token.span.shrink_to_hi();
self.struct_span_err(sp, &msg)
.span_label(self.token.span, "unexpected token")
.span_suggestion_short(sp, "add `;` here", ";", appl)
.emit();
let span = self.prev_token.span.shrink_to_hi();
self.sess.emit_err(ExpectedSemi {
span,
token_descr: super::token_descr_struct(&self.token),
unexpected_token_label: Some(self.token.span),
sugg: ExpectedSemiSugg::AddSemi(span),
});
return Ok(true);
}
}
@ -480,6 +484,7 @@ impl<'a> Parser<'a> {
)
};
self.last_unexpected_token_span = Some(self.token.span);
// FIXME: translation requires list formatting (for `expect`)
let mut err = self.struct_span_err(self.token.span, &msg_exp);
if let TokenKind::Ident(symbol, _) = &self.prev_token.kind {
@ -488,7 +493,7 @@ impl<'a> Parser<'a> {
self.prev_token.span,
&format!("write `fn` instead of `{symbol}` to declare a function"),
"fn",
appl,
Applicability::MachineApplicable,
);
}
}
@ -502,7 +507,7 @@ impl<'a> Parser<'a> {
self.prev_token.span,
"write `pub` instead of `public` to make the item public",
"pub",
appl,
Applicability::MachineApplicable,
);
}