From 972633f53034d7d8d60f4c11b680b3f8f2aff337 Mon Sep 17 00:00:00 2001 From: ardi Date: Sun, 19 May 2024 15:42:12 +0200 Subject: [PATCH] Fix parsing of erroneously placed semicolons --- compiler/rustc_parse/src/parser/item.rs | 12 +++++++++--- .../fn-no-semicolon-issue-124935-semi-after-item.rs | 6 ++++++ ...-no-semicolon-issue-124935-semi-after-item.stderr | 8 ++++++++ tests/ui/parser/issues/issue-49040.rs | 2 +- tests/ui/parser/issues/issue-49040.stderr | 6 +++--- .../missing-main-issue-124935-semi-after-item.rs | 5 +++++ .../missing-main-issue-124935-semi-after-item.stderr | 10 ++++++++++ 7 files changed, 42 insertions(+), 7 deletions(-) create mode 100644 tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.rs create mode 100644 tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.stderr create mode 100644 tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.rs create mode 100644 tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.stderr diff --git a/compiler/rustc_parse/src/parser/item.rs b/compiler/rustc_parse/src/parser/item.rs index a46c104b6d9ca..f43ddadc2ea02 100644 --- a/compiler/rustc_parse/src/parser/item.rs +++ b/compiler/rustc_parse/src/parser/item.rs @@ -58,9 +58,15 @@ impl<'a> Parser<'a> { let attrs = self.parse_inner_attributes()?; 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)); + let mut items: ThinVec> = ThinVec::new(); + + // There shouldn't be any stray semicolons before or after items. + // `parse_item` consumes the appropriate semicolons so any leftover is an error. + loop { + while self.maybe_consume_incorrect_semicolon(items.last().map(|x| &**x)) {} // Eat all bad semicolons + let Some(item) = self.parse_item(ForceCollect::No)? else { + break; + }; items.push(item); } diff --git a/tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.rs b/tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.rs new file mode 100644 index 0000000000000..3c0059ba3e3e3 --- /dev/null +++ b/tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.rs @@ -0,0 +1,6 @@ +// Regression test for issue #124935 +// Tests that we do not erroneously emit an error about +// missing main function when the mod starts with a `;` + +; //~ ERROR expected item, found `;` +fn main() { } diff --git a/tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.stderr b/tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.stderr new file mode 100644 index 0000000000000..9776677589f5b --- /dev/null +++ b/tests/ui/parser/issues/fn-no-semicolon-issue-124935-semi-after-item.stderr @@ -0,0 +1,8 @@ +error: expected item, found `;` + --> $DIR/fn-no-semicolon-issue-124935-semi-after-item.rs:5:1 + | +LL | ; + | ^ help: remove this semicolon + +error: aborting due to 1 previous error + diff --git a/tests/ui/parser/issues/issue-49040.rs b/tests/ui/parser/issues/issue-49040.rs index b7a541dd6642a..68e7cc9f80ebe 100644 --- a/tests/ui/parser/issues/issue-49040.rs +++ b/tests/ui/parser/issues/issue-49040.rs @@ -1,3 +1,3 @@ #![allow(unused_variables)]; //~ ERROR expected item, found `;` -//~^ ERROR `main` function fn foo() {} +//~^ ERROR `main` function diff --git a/tests/ui/parser/issues/issue-49040.stderr b/tests/ui/parser/issues/issue-49040.stderr index 8af7838c79138..11ef5e1aadfd8 100644 --- a/tests/ui/parser/issues/issue-49040.stderr +++ b/tests/ui/parser/issues/issue-49040.stderr @@ -5,10 +5,10 @@ LL | #![allow(unused_variables)]; | ^ help: remove this semicolon error[E0601]: `main` function not found in crate `issue_49040` - --> $DIR/issue-49040.rs:1:29 + --> $DIR/issue-49040.rs:2:12 | -LL | #![allow(unused_variables)]; - | ^ consider adding a `main` function to `$DIR/issue-49040.rs` +LL | fn foo() {} + | ^ consider adding a `main` function to `$DIR/issue-49040.rs` error: aborting due to 2 previous errors diff --git a/tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.rs b/tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.rs new file mode 100644 index 0000000000000..3fbac5fae232f --- /dev/null +++ b/tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.rs @@ -0,0 +1,5 @@ +// Regression test for issue #124935 +// Tests that we still emit an error after an item. + +fn main() { } +; //~ ERROR expected item, found `;` diff --git a/tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.stderr b/tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.stderr new file mode 100644 index 0000000000000..2d7f540443d29 --- /dev/null +++ b/tests/ui/parser/issues/missing-main-issue-124935-semi-after-item.stderr @@ -0,0 +1,10 @@ +error: expected item, found `;` + --> $DIR/missing-main-issue-124935-semi-after-item.rs:5:1 + | +LL | ; + | ^ help: remove this semicolon + | + = help: function declarations are not followed by a semicolon + +error: aborting due to 1 previous error +