Skip to content

Commit

Permalink
improve maybe_consume_incorrect_semicolon
Browse files Browse the repository at this point in the history
  • Loading branch information
dev-ardi committed May 14, 2024
1 parent 58426f4 commit ad84b32
Show file tree
Hide file tree
Showing 6 changed files with 30 additions and 28 deletions.
1 change: 1 addition & 0 deletions compiler/rustc_ast/src/ast.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3250,6 +3250,7 @@ pub enum ItemKind {
}

impl ItemKind {
/// "a" or "an"
pub fn article(&self) -> &'static str {
use ItemKind::*;
match self {
Expand Down
2 changes: 1 addition & 1 deletion compiler/rustc_parse/src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
}

Expand Down
43 changes: 20 additions & 23 deletions compiler/rustc_parse/src/parser/diagnostics.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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<Item>]) -> 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
Expand Down
4 changes: 2 additions & 2 deletions compiler/rustc_parse/src/parser/item.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down
4 changes: 2 additions & 2 deletions src/librustdoc/doctest.rs
Original file line number Diff line number Diff line change
Expand Up @@ -686,9 +686,9 @@ pub(crate) fn make_test(
}
}

// The supplied slice is only used for diagnostics,
// The supplied item is only used for diagnostics,
// which are swallowed here anyway.
parser.maybe_consume_incorrect_semicolon(&[]);
parser.maybe_consume_incorrect_semicolon(None);
}

// Reset errors so that they won't be reported as compiler bugs when dropping the
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@ error: expected item, found `;`
|
LL | mod M {};
| ^ help: remove this semicolon
|
= help: module declarations are not followed by a semicolon

error: expected item, found `;`
--> $DIR/recover-from-semicolon-trailing-item.rs:4:12
Expand All @@ -17,6 +19,8 @@ error: expected item, found `;`
|
LL | fn foo(a: usize) {};
| ^ help: remove this semicolon
|
= help: function declarations are not followed by a semicolon

error[E0308]: mismatched types
--> $DIR/recover-from-semicolon-trailing-item.rs:10:20
Expand Down

0 comments on commit ad84b32

Please sign in to comment.