diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-01-14 20:31:58 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2019-01-14 20:31:58 +0100 |
| commit | b03d414e3c222a7f29259526fcdf95189e61fd0c (patch) | |
| tree | be340379624ea08f4c91342ba54a420889cd4cba /src | |
| parent | feb48f334d29a22f2e3ae3b322af081b42fafc60 (diff) | |
| parent | 3874c7755f292abc87fa2ce4fe82479ad063367e (diff) | |
| download | rust-b03d414e3c222a7f29259526fcdf95189e61fd0c.tar.gz rust-b03d414e3c222a7f29259526fcdf95189e61fd0c.zip | |
Rollup merge of #57585 - estebank:trailing-semicolon, r=petrochenkov
Recover from item trailing semicolon CC https://github.com/rust-lang/rfcs/pull/2479 r? @petrochenkov
Diffstat (limited to 'src')
| -rw-r--r-- | src/libsyntax/parse/parser.rs | 59 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-46186.rs | 3 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-46186.stderr | 4 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-49040.rs | 2 | ||||
| -rw-r--r-- | src/test/ui/issues/issue-49040.stderr | 9 | ||||
| -rw-r--r-- | src/test/ui/suggestions/recover-from-semicolon-trailing-item.rs | 16 | ||||
| -rw-r--r-- | src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr | 50 |
7 files changed, 113 insertions, 30 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 119bd6c107c..823c786bded 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -6482,41 +6482,52 @@ impl<'a> Parser<'a> { } } + fn maybe_consume_incorrect_semicolon(&mut self, items: &[P<Item>]) -> bool { + if self.eat(&token::Semi) { + let mut err = self.struct_span_err(self.prev_span, "expected item, found `;`"); + err.span_suggestion_short_with_applicability( + self.prev_span, + "remove this semicolon", + String::new(), + Applicability::MachineApplicable, + ); + if !items.is_empty() { + let previous_item = &items[items.len()-1]; + let previous_item_kind_name = match previous_item.node { + // 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, + }; + if let Some(name) = previous_item_kind_name { + err.help(&format!("{} declarations are not followed by a semicolon", name)); + } + } + err.emit(); + true + } else { + false + } + } + /// Given a termination token, parse all of the items in a module fn parse_mod_items(&mut self, term: &token::Token, inner_lo: Span) -> PResult<'a, Mod> { let mut items = vec![]; while let Some(item) = self.parse_item()? { items.push(item); + self.maybe_consume_incorrect_semicolon(&items); } if !self.eat(term) { let token_str = self.this_token_descr(); - let mut err = self.fatal(&format!("expected item, found {}", token_str)); - if self.token == token::Semi { - let msg = "consider removing this semicolon"; - err.span_suggestion_short_with_applicability( - self.span, msg, String::new(), Applicability::MachineApplicable - ); - if !items.is_empty() { // Issue #51603 - let previous_item = &items[items.len()-1]; - let previous_item_kind_name = match previous_item.node { - // 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, - }; - if let Some(name) = previous_item_kind_name { - err.help(&format!("{} declarations are not followed by a semicolon", - name)); - } - } - } else { + if !self.maybe_consume_incorrect_semicolon(&items) { + let mut err = self.fatal(&format!("expected item, found {}", token_str)); err.span_label(self.span, "expected item"); + return Err(err); } - return Err(err); } let hi = if self.span.is_dummy() { diff --git a/src/test/ui/issues/issue-46186.rs b/src/test/ui/issues/issue-46186.rs index de7d13a2280..9dfd61fdf3f 100644 --- a/src/test/ui/issues/issue-46186.rs +++ b/src/test/ui/issues/issue-46186.rs @@ -1,5 +1,6 @@ struct Struct { a: usize, -}; //~ ERROR expected item, found `;` +}; +//~^ ERROR expected item, found `;` fn main() {} diff --git a/src/test/ui/issues/issue-46186.stderr b/src/test/ui/issues/issue-46186.stderr index 11a1fc072c9..eb0dbb8aa41 100644 --- a/src/test/ui/issues/issue-46186.stderr +++ b/src/test/ui/issues/issue-46186.stderr @@ -1,8 +1,8 @@ error: expected item, found `;` --> $DIR/issue-46186.rs:3:2 | -LL | }; //~ ERROR expected item, found `;` - | ^ help: consider removing this semicolon +LL | }; + | ^ help: remove this semicolon | = help: braced struct declarations are not followed by a semicolon diff --git a/src/test/ui/issues/issue-49040.rs b/src/test/ui/issues/issue-49040.rs index 7c8d3d0ee69..a5f05d2824e 100644 --- a/src/test/ui/issues/issue-49040.rs +++ b/src/test/ui/issues/issue-49040.rs @@ -1,2 +1,2 @@ #![allow(unused_variables)]; //~ ERROR expected item, found `;` -fn main() {} +fn foo() {} diff --git a/src/test/ui/issues/issue-49040.stderr b/src/test/ui/issues/issue-49040.stderr index eec88f0c3f3..12e78e2f3bc 100644 --- a/src/test/ui/issues/issue-49040.stderr +++ b/src/test/ui/issues/issue-49040.stderr @@ -2,7 +2,12 @@ error: expected item, found `;` --> $DIR/issue-49040.rs:1:28 | LL | #![allow(unused_variables)]; //~ ERROR expected item, found `;` - | ^ help: consider removing this semicolon + | ^ help: remove this semicolon -error: aborting due to previous error +error[E0601]: `main` function not found in crate `issue_49040` + | + = note: consider adding a `main` function to `$DIR/issue-49040.rs` + +error: aborting due to 2 previous errors +For more information about this error, try `rustc --explain E0601`. diff --git a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.rs b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.rs new file mode 100644 index 00000000000..82935af0a81 --- /dev/null +++ b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.rs @@ -0,0 +1,16 @@ +// verify that after encountering a semicolon after an item the parser recovers +mod M {}; +//~^ ERROR expected item, found `;` +struct S {}; +//~^ ERROR expected item, found `;` +fn foo(a: usize) {}; +//~^ ERROR expected item, found `;` +fn main() { + struct X {}; // ok + let _: usize = S {}; + //~^ ERROR mismatched types + let _: usize = X {}; + //~^ ERROR mismatched types + foo(""); + //~^ ERROR mismatched types +} diff --git a/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr new file mode 100644 index 00000000000..9a47a1efb75 --- /dev/null +++ b/src/test/ui/suggestions/recover-from-semicolon-trailing-item.stderr @@ -0,0 +1,50 @@ +error: expected item, found `;` + --> $DIR/recover-from-semicolon-trailing-item.rs:2:9 + | +LL | mod M {}; + | ^ help: remove this semicolon + +error: expected item, found `;` + --> $DIR/recover-from-semicolon-trailing-item.rs:4:12 + | +LL | struct S {}; + | ^ help: remove this semicolon + | + = help: braced struct declarations are not followed by a semicolon + +error: expected item, found `;` + --> $DIR/recover-from-semicolon-trailing-item.rs:6:20 + | +LL | fn foo(a: usize) {}; + | ^ help: remove this semicolon + +error[E0308]: mismatched types + --> $DIR/recover-from-semicolon-trailing-item.rs:10:20 + | +LL | let _: usize = S {}; + | ^^^^ expected usize, found struct `S` + | + = note: expected type `usize` + found type `S` + +error[E0308]: mismatched types + --> $DIR/recover-from-semicolon-trailing-item.rs:12:20 + | +LL | let _: usize = X {}; + | ^^^^ expected usize, found struct `main::X` + | + = note: expected type `usize` + found type `main::X` + +error[E0308]: mismatched types + --> $DIR/recover-from-semicolon-trailing-item.rs:14:9 + | +LL | foo(""); + | ^^ expected usize, found reference + | + = note: expected type `usize` + found type `&'static str` + +error: aborting due to 6 previous errors + +For more information about this error, try `rustc --explain E0308`. |
