From 8dc6a5d145af86955402ec02907dda77dcb4a122 Mon Sep 17 00:00:00 2001 From: ardi Date: Tue, 14 May 2024 12:23:33 +0200 Subject: improve maybe_consume_incorrect_semicolon --- compiler/rustc_parse/src/errors.rs | 2 +- compiler/rustc_parse/src/parser/diagnostics.rs | 43 ++++++++++++-------------- compiler/rustc_parse/src/parser/item.rs | 4 +-- 3 files changed, 23 insertions(+), 26 deletions(-) (limited to 'compiler/rustc_parse') diff --git a/compiler/rustc_parse/src/errors.rs b/compiler/rustc_parse/src/errors.rs index 2f68a299f26..3f08a830b0c 100644 --- a/compiler/rustc_parse/src/errors.rs +++ b/compiler/rustc_parse/src/errors.rs @@ -83,7 +83,7 @@ pub(crate) struct IncorrectSemicolon<'a> { #[suggestion(style = "short", code = "", applicability = "machine-applicable")] pub span: Span, #[help] - pub opt_help: Option<()>, + pub show_help: bool, pub name: &'a str, } diff --git a/compiler/rustc_parse/src/parser/diagnostics.rs b/compiler/rustc_parse/src/parser/diagnostics.rs index 63762f64be9..46809847fdb 100644 --- a/compiler/rustc_parse/src/parser/diagnostics.rs +++ b/compiler/rustc_parse/src/parser/diagnostics.rs @@ -1817,34 +1817,31 @@ impl<'a> Parser<'a> { Ok(P(T::recovered(Some(P(QSelf { ty, path_span, position: 0 })), path))) } - pub fn maybe_consume_incorrect_semicolon(&mut self, items: &[P]) -> bool { - if self.token.kind == TokenKind::Semi { - self.bump(); - - let mut err = - IncorrectSemicolon { span: self.prev_token.span, opt_help: None, name: "" }; + /// This function gets called in places where a semicolon is NOT expected and if there's a + /// semicolon it emits the appropriate error and returns true. + pub fn maybe_consume_incorrect_semicolon(&mut self, previous_item: Option<&Item>) -> bool { + if self.token.kind != TokenKind::Semi { + return false; + } - if !items.is_empty() { - let previous_item = &items[items.len() - 1]; - let previous_item_kind_name = match previous_item.kind { + // Check previous item to add it to the diagnostic, for example to say + // `enum declarations are not followed by a semicolon` + let err = match previous_item { + Some(previous_item) => { + let name = match previous_item.kind { // Say "braced struct" because tuple-structs and // braceless-empty-struct declarations do take a semicolon. - ItemKind::Struct(..) => Some("braced struct"), - ItemKind::Enum(..) => Some("enum"), - ItemKind::Trait(..) => Some("trait"), - ItemKind::Union(..) => Some("union"), - _ => None, + ItemKind::Struct(..) => "braced struct", + _ => previous_item.kind.descr(), }; - if let Some(name) = previous_item_kind_name { - err.opt_help = Some(()); - err.name = name; - } + IncorrectSemicolon { span: self.token.span, name, show_help: true } } - self.dcx().emit_err(err); - true - } else { - false - } + None => IncorrectSemicolon { span: self.token.span, name: "", show_help: false }, + }; + self.dcx().emit_err(err); + + self.bump(); + true } /// Creates a `Diag` for an unexpected token `t` and tries to recover if it is a diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index 29957bd2f71..2a82a95dd07 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -59,13 +59,13 @@ impl<'a> Parser<'a> { let post_attr_lo = self.token.span; let mut items = ThinVec::new(); while let Some(item) = self.parse_item(ForceCollect::No)? { + self.maybe_consume_incorrect_semicolon(Some(&item)); items.push(item); - self.maybe_consume_incorrect_semicolon(&items); } if !self.eat(term) { let token_str = super::token_descr(&self.token); - if !self.maybe_consume_incorrect_semicolon(&items) { + if !self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) { let msg = format!("expected item, found {token_str}"); let mut err = self.dcx().struct_span_err(self.token.span, msg); let span = self.token.span; -- cgit 1.4.1-3-g733a5