Skip to content

Commit

Permalink
Auto merge of #59031 - estebank:recover-from-comaless, r=petrochenkov
Browse files Browse the repository at this point in the history
Recover from missing comma between enum variants and from bad `pub` kw

Fix #56579. Fix #56473.
  • Loading branch information
bors committed Mar 22, 2019
2 parents 86466a3 + 0a09e76 commit a85ec7c
Show file tree
Hide file tree
Showing 11 changed files with 78 additions and 43 deletions.
36 changes: 33 additions & 3 deletions src/libsyntax/parse/parser.rs
Original file line number Diff line number Diff line change
Expand Up @@ -1524,7 +1524,7 @@ impl<'a> Parser<'a> {
at_end: &mut bool,
mut attrs: Vec<Attribute>) -> PResult<'a, TraitItem> {
let lo = self.span;

self.eat_bad_pub();
let (name, node, generics) = if self.eat_keyword(keywords::Type) {
self.parse_trait_item_assoc_ty()?
} else if self.is_const_item() {
Expand Down Expand Up @@ -7688,6 +7688,7 @@ impl<'a> Parser<'a> {

let struct_def;
let mut disr_expr = None;
self.eat_bad_pub();
let ident = self.parse_ident()?;
if self.check(&token::OpenDelim(token::Brace)) {
// Parse a struct variant.
Expand Down Expand Up @@ -7719,11 +7720,25 @@ impl<'a> Parser<'a> {
};
variants.push(respan(vlo.to(self.prev_span), vr));

if !self.eat(&token::Comma) { break; }
if !self.eat(&token::Comma) {
if self.token.is_ident() && !self.token.is_reserved_ident() {
let sp = self.sess.source_map().next_point(self.prev_span);
let mut err = self.struct_span_err(sp, "missing comma");
err.span_suggestion_short(
sp,
"missing comma",
",".to_owned(),
Applicability::MaybeIncorrect,
);
err.emit();
} else {
break;
}
}
}
self.expect(&token::CloseDelim(token::Brace))?;
if !any_disr.is_empty() && !all_nullary {
let mut err =self.struct_span_err(
let mut err = self.struct_span_err(
any_disr.clone(),
"discriminator values can only be used with a field-less enum",
);
Expand Down Expand Up @@ -8608,6 +8623,21 @@ impl<'a> Parser<'a> {
Applicability::MaybeIncorrect,
).emit();
}

/// Recover from `pub` keyword in places where it seems _reasonable_ but isn't valid.
fn eat_bad_pub(&mut self) {
if self.token.is_keyword(keywords::Pub) {
match self.parse_visibility(false) {
Ok(vis) => {
let mut err = self.diagnostic()
.struct_span_err(vis.span, "unnecessary visibility qualifier");
err.span_label(vis.span, "`pub` not permitted here");
err.emit();
}
Err(mut err) => err.emit(),
}
}
}
}

pub fn emit_unclosed_delims(unclosed_delims: &mut Vec<UnmatchedBrace>, handler: &errors::Handler) {
Expand Down
13 changes: 7 additions & 6 deletions src/test/ui/issues/issue-28433.rs
Original file line number Diff line number Diff line change
@@ -1,13 +1,14 @@
// compile-flags: -Z continue-parse-after-error

enum bird {
pub duck,
//~^ ERROR: expected identifier, found keyword `pub`
//~| ERROR: expected
goose
enum Bird {
pub Duck,
//~^ ERROR unnecessary visibility qualifier
Goose,
pub(crate) Dove
//~^ ERROR unnecessary visibility qualifier
}


fn main() {
let y = bird::goose;
let y = Bird::Goose;
}
18 changes: 7 additions & 11 deletions src/test/ui/issues/issue-28433.stderr
Original file line number Diff line number Diff line change
@@ -1,18 +1,14 @@
error: expected identifier, found keyword `pub`
error: unnecessary visibility qualifier
--> $DIR/issue-28433.rs:4:5
|
LL | pub duck,
| ^^^ expected identifier, found keyword
help: you can escape reserved keywords to use them as identifiers
|
LL | r#pub duck,
| ^^^^^
LL | pub Duck,
| ^^^ `pub` not permitted here

error: expected one of `(`, `,`, `=`, `{`, or `}`, found `duck`
--> $DIR/issue-28433.rs:4:9
error: unnecessary visibility qualifier
--> $DIR/issue-28433.rs:7:5
|
LL | pub duck,
| ^^^^ expected one of `(`, `,`, `=`, `{`, or `}` here
LL | pub(crate) Dove
| ^^^^^^^^^^ `pub` not permitted here

error: aborting due to 2 previous errors

8 changes: 6 additions & 2 deletions src/test/ui/parser/recover-enum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@
fn main() {
enum Test {
Very
Bad //~ ERROR found `Bad`
Stuff
//~^ ERROR missing comma
Bad(usize)
//~^ ERROR missing comma
Stuff { a: usize }
//~^ ERROR missing comma
Here
}
}
22 changes: 16 additions & 6 deletions src/test/ui/parser/recover-enum.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,20 @@
error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
--> $DIR/recover-enum.rs:6:9
error: missing comma
--> $DIR/recover-enum.rs:5:13
|
LL | Very
| - expected one of `(`, `,`, `=`, `{`, or `}` here
LL | Bad
| ^^^ unexpected token
| ^ help: missing comma

error: aborting due to previous error
error: missing comma
--> $DIR/recover-enum.rs:7:19
|
LL | Bad(usize)
| ^ help: missing comma

error: missing comma
--> $DIR/recover-enum.rs:9:27
|
LL | Stuff { a: usize }
| ^ help: missing comma

error: aborting due to 3 previous errors

2 changes: 1 addition & 1 deletion src/test/ui/parser/trait-pub-assoc-const.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
trait Foo {
pub const Foo: u32;
//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
//~^ ERROR unnecessary visibility qualifier
}

fn main() {}
6 changes: 2 additions & 4 deletions src/test/ui/parser/trait-pub-assoc-const.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
error: unnecessary visibility qualifier
--> $DIR/trait-pub-assoc-const.rs:2:5
|
LL | trait Foo {
| - expected one of 7 possible tokens here
LL | pub const Foo: u32;
| ^^^ unexpected token
| ^^^ `pub` not permitted here

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/parser/trait-pub-assoc-ty.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
trait Foo {
pub type Foo;
//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
//~^ ERROR unnecessary visibility qualifier
}

fn main() {}
6 changes: 2 additions & 4 deletions src/test/ui/parser/trait-pub-assoc-ty.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
error: unnecessary visibility qualifier
--> $DIR/trait-pub-assoc-ty.rs:2:5
|
LL | trait Foo {
| - expected one of 7 possible tokens here
LL | pub type Foo;
| ^^^ unexpected token
| ^^^ `pub` not permitted here

error: aborting due to previous error

2 changes: 1 addition & 1 deletion src/test/ui/parser/trait-pub-method.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
trait Foo {
pub fn foo();
//~^ ERROR expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found
//~^ ERROR unnecessary visibility qualifier
}

fn main() {}
6 changes: 2 additions & 4 deletions src/test/ui/parser/trait-pub-method.stderr
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
error: expected one of `async`, `const`, `extern`, `fn`, `type`, `unsafe`, or `}`, found `pub`
error: unnecessary visibility qualifier
--> $DIR/trait-pub-method.rs:2:5
|
LL | trait Foo {
| - expected one of 7 possible tokens here
LL | pub fn foo();
| ^^^ unexpected token
| ^^^ `pub` not permitted here

error: aborting due to previous error

0 comments on commit a85ec7c

Please sign in to comment.