]> git.lizzy.rs Git - rust.git/commitdiff
Migrate "expected semicolon" diagnostics to diagnostic structs
authorXiretza <xiretza@xiretza.xyz>
Sun, 4 Sep 2022 18:12:00 +0000 (20:12 +0200)
committerXiretza <xiretza@xiretza.xyz>
Tue, 27 Sep 2022 18:29:19 +0000 (20:29 +0200)
compiler/rustc_error_messages/locales/en-US/parser.ftl
compiler/rustc_parse/src/errors.rs
compiler/rustc_parse/src/parser/diagnostics.rs

index 61450e288b4eb1c97dc308dc7ceeff72f8ebe9f1..22fb65f02680d5514276a19a1136898ac6aaa1c1 100644 (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
index 3b86dd15747150c89432d5d00f1875e988821d93..07785b7344f2549387856050a1b106ca6a81da9a 100644 (file)
@@ -963,3 +963,54 @@ fn into_diagnostic(
         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),
+}
index 8c2a925a231681eb3e00da265ac554c91600be45..ba48e4e1c2525af306fe0bcd57ba933a45c29aba 100644 (file)
@@ -4,9 +4,9 @@
     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 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
         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 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
                 //
                 //   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 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
                 //
                 //   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 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
             )
         };
         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 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
                     self.prev_token.span,
                     &format!("write `fn` instead of `{symbol}` to declare a function"),
                     "fn",
-                    appl,
+                    Applicability::MachineApplicable,
                 );
             }
         }
@@ -502,7 +507,7 @@ fn is_ident_eq_keyword(found: &TokenKind, expected: &TokenType) -> bool {
                 self.prev_token.span,
                 "write `pub` instead of `public` to make the item public",
                 "pub",
-                appl,
+                Applicability::MachineApplicable,
             );
         }