about summary refs log tree commit diff
diff options
context:
space:
mode:
authorbors <bors@rust-lang.org>2019-03-22 04:52:10 +0000
committerbors <bors@rust-lang.org>2019-03-22 04:52:10 +0000
commita85ec7c2c005c1c2f85050151706c6301720760a (patch)
tree41f2c043693b15238fadb7336cbcc97b8898ce1d
parent86466a397a4e43115231b66cf7935c7390f1aed2 (diff)
parent0a09e76c967cfe0eb43ccdf1bddc715cd3b81f41 (diff)
downloadrust-a85ec7c2c005c1c2f85050151706c6301720760a.tar.gz
rust-a85ec7c2c005c1c2f85050151706c6301720760a.zip
Auto merge of #59031 - estebank:recover-from-comaless, r=petrochenkov
Recover from missing comma between enum variants and from bad `pub` kw

Fix #56579. Fix #56473.
-rw-r--r--src/libsyntax/parse/parser.rs36
-rw-r--r--src/test/ui/issues/issue-28433.rs13
-rw-r--r--src/test/ui/issues/issue-28433.stderr18
-rw-r--r--src/test/ui/parser/recover-enum.rs8
-rw-r--r--src/test/ui/parser/recover-enum.stderr22
-rw-r--r--src/test/ui/parser/trait-pub-assoc-const.rs2
-rw-r--r--src/test/ui/parser/trait-pub-assoc-const.stderr6
-rw-r--r--src/test/ui/parser/trait-pub-assoc-ty.rs2
-rw-r--r--src/test/ui/parser/trait-pub-assoc-ty.stderr6
-rw-r--r--src/test/ui/parser/trait-pub-method.rs2
-rw-r--r--src/test/ui/parser/trait-pub-method.stderr6
11 files changed, 78 insertions, 43 deletions
diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs
index 3e00d948c1a..7a4a687f90e 100644
--- a/src/libsyntax/parse/parser.rs
+++ b/src/libsyntax/parse/parser.rs
@@ -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() {
@@ -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.
@@ -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",
             );
@@ -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) {
diff --git a/src/test/ui/issues/issue-28433.rs b/src/test/ui/issues/issue-28433.rs
index a87ac63784f..2bbb32bf2b3 100644
--- a/src/test/ui/issues/issue-28433.rs
+++ b/src/test/ui/issues/issue-28433.rs
@@ -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;
 }
diff --git a/src/test/ui/issues/issue-28433.stderr b/src/test/ui/issues/issue-28433.stderr
index d3cba3aae71..cfdbf6c7287 100644
--- a/src/test/ui/issues/issue-28433.stderr
+++ b/src/test/ui/issues/issue-28433.stderr
@@ -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
 
diff --git a/src/test/ui/parser/recover-enum.rs b/src/test/ui/parser/recover-enum.rs
index 204ad857165..da42da84acf 100644
--- a/src/test/ui/parser/recover-enum.rs
+++ b/src/test/ui/parser/recover-enum.rs
@@ -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
     }
 }
diff --git a/src/test/ui/parser/recover-enum.stderr b/src/test/ui/parser/recover-enum.stderr
index 8c3448d6fbe..10b4aba4053 100644
--- a/src/test/ui/parser/recover-enum.stderr
+++ b/src/test/ui/parser/recover-enum.stderr
@@ -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
 
diff --git a/src/test/ui/parser/trait-pub-assoc-const.rs b/src/test/ui/parser/trait-pub-assoc-const.rs
index 3ee2dc1ae18..219ffa309c2 100644
--- a/src/test/ui/parser/trait-pub-assoc-const.rs
+++ b/src/test/ui/parser/trait-pub-assoc-const.rs
@@ -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() {}
diff --git a/src/test/ui/parser/trait-pub-assoc-const.stderr b/src/test/ui/parser/trait-pub-assoc-const.stderr
index 8fc9ae4cf28..817692cc82c 100644
--- a/src/test/ui/parser/trait-pub-assoc-const.stderr
+++ b/src/test/ui/parser/trait-pub-assoc-const.stderr
@@ -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
 
diff --git a/src/test/ui/parser/trait-pub-assoc-ty.rs b/src/test/ui/parser/trait-pub-assoc-ty.rs
index 042addfd1a4..a78dfbdcdda 100644
--- a/src/test/ui/parser/trait-pub-assoc-ty.rs
+++ b/src/test/ui/parser/trait-pub-assoc-ty.rs
@@ -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() {}
diff --git a/src/test/ui/parser/trait-pub-assoc-ty.stderr b/src/test/ui/parser/trait-pub-assoc-ty.stderr
index b8eab4e87bf..400be6af22a 100644
--- a/src/test/ui/parser/trait-pub-assoc-ty.stderr
+++ b/src/test/ui/parser/trait-pub-assoc-ty.stderr
@@ -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
 
diff --git a/src/test/ui/parser/trait-pub-method.rs b/src/test/ui/parser/trait-pub-method.rs
index 9675182c156..1f6ee028a17 100644
--- a/src/test/ui/parser/trait-pub-method.rs
+++ b/src/test/ui/parser/trait-pub-method.rs
@@ -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() {}
diff --git a/src/test/ui/parser/trait-pub-method.stderr b/src/test/ui/parser/trait-pub-method.stderr
index d4db961c3fa..b3617a4aa9b 100644
--- a/src/test/ui/parser/trait-pub-method.stderr
+++ b/src/test/ui/parser/trait-pub-method.stderr
@@ -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