Skip to content

Commit ba10f2c

Browse files
committed
Migrate "expected semicolon" diagnostics to diagnostic structs
1 parent 7507ee2 commit ba10f2c

File tree

3 files changed

+82
-16
lines changed

3 files changed

+82
-16
lines changed

compiler/rustc_error_messages/locales/en-US/parser.ftl

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -306,3 +306,13 @@ parser_expected_identifier = expected identifier
306306
parser_sugg_escape_to_use_as_identifier = escape `{$ident_name}` to use it as an identifier
307307
308308
parser_sugg_remove_comma = remove this comma
309+
310+
parser_expected_semi_found_reserved_identifier_str = expected `;`, found reserved identifier `{$token_str}`
311+
parser_expected_semi_found_keyword_str = expected `;`, found keyword `{$token_str}`
312+
parser_expected_semi_found_reserved_keyword_str = expected `;`, found reserved keyword `{$token_str}`
313+
parser_expected_semi_found_doc_comment_str = expected `;`, found doc comment `{$token_str}`
314+
parser_expected_semi_found_str = expected `;`, found `{$token_str}`
315+
316+
parser_sugg_change_this_to_semi = change this to `;`
317+
parser_sugg_add_semi = add `;` here
318+
parser_label_unexpected_token = unexpected token

compiler/rustc_parse/src/errors.rs

Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -963,3 +963,54 @@ impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedIdentifier {
963963
diag
964964
}
965965
}
966+
967+
pub(crate) struct ExpectedSemi {
968+
pub span: Span,
969+
pub token_descr: TokenDescription,
970+
971+
pub unexpected_token_label: Option<Span>,
972+
pub sugg: ExpectedSemiSugg,
973+
}
974+
975+
impl<'a, G: EmissionGuarantee> IntoDiagnostic<'a, G> for ExpectedSemi {
976+
fn into_diagnostic(
977+
self,
978+
handler: &'a rustc_errors::Handler,
979+
) -> rustc_errors::DiagnosticBuilder<'a, G> {
980+
let mut diag = handler.struct_diagnostic(match self.token_descr.kind {
981+
Some(TokenDescriptionKind::ReservedIdentifier) => {
982+
fluent::parser::expected_semi_found_reserved_identifier_str
983+
}
984+
Some(TokenDescriptionKind::Keyword) => fluent::parser::expected_semi_found_keyword_str,
985+
Some(TokenDescriptionKind::ReservedKeyword) => {
986+
fluent::parser::expected_semi_found_reserved_keyword_str
987+
}
988+
Some(TokenDescriptionKind::DocComment) => {
989+
fluent::parser::expected_semi_found_doc_comment_str
990+
}
991+
None => fluent::parser::expected_semi_found_str,
992+
});
993+
diag.set_span(self.span);
994+
diag.set_arg("token_str", self.token_descr.name);
995+
996+
if let Some(unexpected_token_label) = self.unexpected_token_label {
997+
diag.span_label(unexpected_token_label, fluent::parser::label_unexpected_token);
998+
}
999+
1000+
self.sugg.add_to_diagnostic(&mut diag);
1001+
1002+
diag
1003+
}
1004+
}
1005+
1006+
#[derive(Subdiagnostic)]
1007+
pub(crate) enum ExpectedSemiSugg {
1008+
#[suggestion(
1009+
parser::sugg_change_this_to_semi,
1010+
code = ";",
1011+
applicability = "machine-applicable"
1012+
)]
1013+
ChangeToSemi(#[primary_span] Span),
1014+
#[suggestion_short(parser::sugg_add_semi, code = ";", applicability = "machine-applicable")]
1015+
AddSemi(#[primary_span] Span),
1016+
}

compiler/rustc_parse/src/parser/diagnostics.rs

Lines changed: 21 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,9 @@ use super::{
44
TokenExpectType, TokenType,
55
};
66
use crate::errors::{
7-
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, ExpectedIdentifier, InInTypo,
8-
IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait, SuggEscapeToUseAsIdentifier,
9-
SuggRemoveComma, UseEqInstead,
7+
AmbiguousPlus, BadQPathStage2, BadTypePlus, BadTypePlusSub, ExpectedIdentifier, ExpectedSemi,
8+
ExpectedSemiSugg, InInTypo, IncorrectAwait, IncorrectSemicolon, IncorrectUseOfAwait,
9+
SuggEscapeToUseAsIdentifier, SuggRemoveComma, UseEqInstead,
1010
};
1111

1212
use crate::lexer::UnmatchedBrace;
@@ -388,8 +388,8 @@ impl<'a> Parser<'a> {
388388
expected.dedup();
389389

390390
let sm = self.sess.source_map();
391-
let msg = format!("expected `;`, found {}", super::token_descr(&self.token));
392-
let appl = Applicability::MachineApplicable;
391+
392+
// Special-case "expected `;`" errors
393393
if expected.contains(&TokenType::Token(token::Semi)) {
394394
if self.token.span == DUMMY_SP || self.prev_token.span == DUMMY_SP {
395395
// Likely inside a macro, can't provide meaningful suggestions.
@@ -417,11 +417,13 @@ impl<'a> Parser<'a> {
417417
//
418418
// let x = 32:
419419
// let y = 42;
420+
self.sess.emit_err(ExpectedSemi {
421+
span: self.token.span,
422+
token_descr: super::token_descr_struct(&self.token),
423+
unexpected_token_label: None,
424+
sugg: ExpectedSemiSugg::ChangeToSemi(self.token.span),
425+
});
420426
self.bump();
421-
let sp = self.prev_token.span;
422-
self.struct_span_err(sp, &msg)
423-
.span_suggestion_short(sp, "change this to `;`", ";", appl)
424-
.emit();
425427
return Ok(true);
426428
} else if self.look_ahead(0, |t| {
427429
t == &token::CloseDelim(Delimiter::Brace)
@@ -439,11 +441,13 @@ impl<'a> Parser<'a> {
439441
//
440442
// let x = 32
441443
// let y = 42;
442-
let sp = self.prev_token.span.shrink_to_hi();
443-
self.struct_span_err(sp, &msg)
444-
.span_label(self.token.span, "unexpected token")
445-
.span_suggestion_short(sp, "add `;` here", ";", appl)
446-
.emit();
444+
let span = self.prev_token.span.shrink_to_hi();
445+
self.sess.emit_err(ExpectedSemi {
446+
span,
447+
token_descr: super::token_descr_struct(&self.token),
448+
unexpected_token_label: Some(self.token.span),
449+
sugg: ExpectedSemiSugg::AddSemi(span),
450+
});
447451
return Ok(true);
448452
}
449453
}
@@ -480,6 +484,7 @@ impl<'a> Parser<'a> {
480484
)
481485
};
482486
self.last_unexpected_token_span = Some(self.token.span);
487+
// FIXME: translation requires list formatting (for `expect`)
483488
let mut err = self.struct_span_err(self.token.span, &msg_exp);
484489

485490
if let TokenKind::Ident(symbol, _) = &self.prev_token.kind {
@@ -488,7 +493,7 @@ impl<'a> Parser<'a> {
488493
self.prev_token.span,
489494
&format!("write `fn` instead of `{symbol}` to declare a function"),
490495
"fn",
491-
appl,
496+
Applicability::MachineApplicable,
492497
);
493498
}
494499
}
@@ -502,7 +507,7 @@ impl<'a> Parser<'a> {
502507
self.prev_token.span,
503508
"write `pub` instead of `public` to make the item public",
504509
"pub",
505-
appl,
510+
Applicability::MachineApplicable,
506511
);
507512
}
508513

0 commit comments

Comments
 (0)