1
Fork 0

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