Skip to content

Commit a56bd54

Browse files
committed
Fix parsing of erroneously placed semicolons
1 parent 7c73595 commit a56bd54

7 files changed

+45
-6
lines changed

compiler/rustc_parse/src/parser/item.rs

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,20 @@ impl<'a> Parser<'a> {
5959

6060
let post_attr_lo = self.token.span;
6161
let mut items = ThinVec::new();
62-
while let Some(item) = self.parse_item(ForceCollect::No)? {
63-
self.maybe_consume_incorrect_semicolon(Some(&item));
62+
63+
// There shouldn't be any semicolons before or afer items.
64+
// `parse_item` consumes the appropriate semicolons so any leftover is an error.
65+
let mut last = None;
66+
loop {
67+
while self.maybe_consume_incorrect_semicolon(last) {} // Eat all bad semicolons
68+
let Some(item) = self.parse_item(ForceCollect::No)? else {
69+
break;
70+
};
6471
items.push(item);
72+
last = items.last().map(|x| &**x);
6573
}
74+
// Handle trailing semicolon at the end of the module
75+
self.maybe_consume_incorrect_semicolon(last);
6676

6777
if !self.eat(term) {
6878
let token_str = super::token_descr(&self.token);
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
// Regression test for issue #124935
2+
// Tests that we do not erroneously emit an error about
3+
// missing main function when the mod starts with a `;`
4+
5+
; //~ ERROR expected item, found `;`
6+
fn main() { }
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
error: expected item, found `;`
2+
--> $DIR/fn-no-semicolon-issue-124935-semi-after-item.rs:5:1
3+
|
4+
LL | ;
5+
| ^ help: remove this semicolon
6+
7+
error: aborting due to 1 previous error
8+

tests/ui/parser/issues/issue-49040.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
11
#![allow(unused_variables)]; //~ ERROR expected item, found `;`
2-
//~^ ERROR `main` function
32
fn foo() {}
3+
//~^ ERROR `main` function

tests/ui/parser/issues/issue-49040.stderr

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ LL | #![allow(unused_variables)];
55
| ^ help: remove this semicolon
66

77
error[E0601]: `main` function not found in crate `issue_49040`
8-
--> $DIR/issue-49040.rs:1:29
8+
--> $DIR/issue-49040.rs:2:12
99
|
10-
LL | #![allow(unused_variables)];
11-
| ^ consider adding a `main` function to `$DIR/issue-49040.rs`
10+
LL | fn foo() {}
11+
| ^ consider adding a `main` function to `$DIR/issue-49040.rs`
1212

1313
error: aborting due to 2 previous errors
1414

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
// Regression test for issue #124935
2+
// Tests that we still emit an error after an item.
3+
4+
fn main() { }
5+
; //~ ERROR expected item, found `;`
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
error: expected item, found `;`
2+
--> $DIR/missing-main-issue-124935-semi-after-item.rs:5:1
3+
|
4+
LL | ;
5+
| ^ help: remove this semicolon
6+
|
7+
= help: function declarations are not followed by a semicolon
8+
9+
error: aborting due to 1 previous error
10+

0 commit comments

Comments
 (0)