about summary refs log tree commit diff
path: root/src
diff options
context:
space:
mode:
authorJanusz Marcinkiewicz <virrages@gmail.com>2019-11-24 22:33:00 +0100
committerJanusz Marcinkiewicz <virrages@gmail.com>2019-11-26 19:24:36 +0100
commit5c34a11324b060b0492eb390c7e9b2abc9eb61a4 (patch)
tree438cec38e8b05d843e8fdabc7c2dbb6c0a0fa5a8 /src
parent7d761fe0462ba0f671a237d0bb35e3579b8ba0e8 (diff)
downloadrust-5c34a11324b060b0492eb390c7e9b2abc9eb61a4.tar.gz
rust-5c34a11324b060b0492eb390c7e9b2abc9eb61a4.zip
Refactor 'parse_enum_item' to use 'parse_delim_comma_seq'
Diffstat (limited to 'src')
-rw-r--r--src/librustc_parse/parser/item.rs115
-rw-r--r--src/librustc_parse/parser/mod.rs22
-rw-r--r--src/test/ui/on-unimplemented/expected-comma-found-token.stderr5
-rw-r--r--src/test/ui/parser/pat-lt-bracket-6.stderr5
-rw-r--r--src/test/ui/parser/pat-lt-bracket-7.stderr5
-rw-r--r--src/test/ui/parser/recover-enum.rs12
-rw-r--r--src/test/ui/parser/recover-enum.stderr35
-rw-r--r--src/test/ui/similar-tokens.stderr5
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test.stderr4
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test2.stderr4
-rw-r--r--src/test/ui/tuple/tuple-struct-fields/test3.stderr4
11 files changed, 124 insertions, 92 deletions
diff --git a/src/librustc_parse/parser/item.rs b/src/librustc_parse/parser/item.rs
index 2c9d4004226..7569269921a 100644
--- a/src/librustc_parse/parser/item.rs
+++ b/src/librustc_parse/parser/item.rs
@@ -7,7 +7,7 @@ use syntax::ast::{self, DUMMY_NODE_ID, Ident, Attribute, AttrKind, AttrStyle, An
 use syntax::ast::{ItemKind, ImplItem, ImplItemKind, TraitItem, TraitItemKind, UseTree, UseTreeKind};
 use syntax::ast::{PathSegment, IsAuto, Constness, IsAsync, Unsafety, Defaultness, Extern, StrLit};
 use syntax::ast::{Visibility, VisibilityKind, Mutability, FnHeader, ForeignItem, ForeignItemKind};
-use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, VariantData, StructField};
+use syntax::ast::{Ty, TyKind, Generics, TraitRef, EnumDef, Variant, VariantData, StructField};
 use syntax::ast::{Mac, MacDelimiter, Block, BindingMode, FnDecl, FnSig, SelfKind, Param};
 use syntax::print::pprust;
 use syntax::ptr::P;
@@ -1324,85 +1324,65 @@ impl<'a> Parser<'a> {
         let id = self.parse_ident()?;
         let mut generics = self.parse_generics()?;
         generics.where_clause = self.parse_where_clause()?;
-        self.expect(&token::OpenDelim(token::Brace))?;
 
-        let enum_definition = self.parse_enum_def(&generics).map_err(|e| {
+        let (variants, _) = self.parse_delim_comma_seq(
+            token::Brace,
+            |p| p.parse_enum_item(),
+        ).map_err(|e| {
             self.recover_stmt();
-            self.eat(&token::CloseDelim(token::Brace));
             e
         })?;
+
+        let enum_definition = EnumDef {
+            variants: variants.into_iter().filter_map(|v| v).collect(),
+        };
         Ok((id, ItemKind::Enum(enum_definition, generics), None))
     }
 
-    /// Parses the part of an enum declaration following the `{`.
-    fn parse_enum_def(&mut self, _generics: &Generics) -> PResult<'a, EnumDef> {
-        let mut variants = Vec::new();
-        // FIXME: Consider using `parse_delim_comma_seq`.
-        // We could then remove eating comma in `recover_nested_adt_item`.
-        while self.token != token::CloseDelim(token::Brace) {
-            let variant_attrs = self.parse_outer_attributes()?;
-            let vlo = self.token.span;
-
-            let vis = self.parse_visibility(FollowedByType::No)?;
-            if !self.recover_nested_adt_item(kw::Enum)? {
-                // Item already parsed, we need to skip this variant.
-                continue
-            }
-            let ident = self.parse_ident()?;
+    fn parse_enum_item(&mut self) -> PResult<'a, Option<Variant>> {
+        let variant_attrs = self.parse_outer_attributes()?;
+        let vlo = self.token.span;
 
-            let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
-                // Parse a struct variant.
-                let (fields, recovered) = self.parse_record_struct_body()?;
-                VariantData::Struct(fields, recovered)
-            } else if self.check(&token::OpenDelim(token::Paren)) {
-                VariantData::Tuple(
-                    self.parse_tuple_struct_body()?,
-                    DUMMY_NODE_ID,
-                )
-            } else {
-                VariantData::Unit(DUMMY_NODE_ID)
-            };
+        let vis = self.parse_visibility(FollowedByType::No)?;
+        if !self.recover_nested_adt_item(kw::Enum)? {
+            return Ok(None)
+        }
+        let ident = self.parse_ident()?;
 
-            let disr_expr = if self.eat(&token::Eq) {
-                Some(AnonConst {
-                    id: DUMMY_NODE_ID,
-                    value: self.parse_expr()?,
-                })
-            } else {
-                None
-            };
+        let struct_def = if self.check(&token::OpenDelim(token::Brace)) {
+            // Parse a struct variant.
+            let (fields, recovered) = self.parse_record_struct_body()?;
+            VariantData::Struct(fields, recovered)
+        } else if self.check(&token::OpenDelim(token::Paren)) {
+            VariantData::Tuple(
+                self.parse_tuple_struct_body()?,
+                DUMMY_NODE_ID,
+            )
+        } else {
+            VariantData::Unit(DUMMY_NODE_ID)
+        };
 
-            let vr = ast::Variant {
-                ident,
-                vis,
+        let disr_expr = if self.eat(&token::Eq) {
+            Some(AnonConst {
                 id: DUMMY_NODE_ID,
-                attrs: variant_attrs,
-                data: struct_def,
-                disr_expr,
-                span: vlo.to(self.prev_span),
-                is_placeholder: false,
-            };
-            variants.push(vr);
+                value: self.parse_expr()?,
+            })
+        } else {
+            None
+        };
 
-            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);
-                    self.struct_span_err(sp, "missing comma")
-                        .span_suggestion_short(
-                            sp,
-                            "missing comma",
-                            ",".to_owned(),
-                            Applicability::MaybeIncorrect,
-                        )
-                        .emit();
-                } else {
-                    break;
-                }
-            }
-        }
-        self.expect(&token::CloseDelim(token::Brace))?;
+        let vr = ast::Variant {
+            ident,
+            vis,
+            id: DUMMY_NODE_ID,
+            attrs: variant_attrs,
+            data: struct_def,
+            disr_expr,
+            span: vlo.to(self.prev_span),
+            is_placeholder: false,
+        };
 
-        Ok(ast::EnumDef { variants })
+        Ok(Some(vr))
     }
 
     /// Parses `struct Foo { ... }`.
@@ -1759,7 +1739,6 @@ impl<'a> Parser<'a> {
             let kw_token = self.token.clone();
             let kw_str = pprust::token_to_string(&kw_token);
             let item = self.parse_item()?;
-            self.eat(&token::Comma);
 
             self.struct_span_err(
                 kw_token.span,
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index d810117662c..ea7673767d0 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -805,21 +805,39 @@ impl<'a> Parser<'a> {
                             recovered = true;
                             break;
                         }
-                        Err(mut e) => {
+                        Err(mut expect_err) => {
+                            let sp = self.sess.source_map().next_point(self.prev_span);
+                            let token_str = pprust::token_kind_to_string(t);
+
                             // Attempt to keep parsing if it was a similar separator.
                             if let Some(ref tokens) = t.similar_tokens() {
                                 if tokens.contains(&self.token.kind) {
                                     self.bump();
                                 }
                             }
-                            e.emit();
+
                             // Attempt to keep parsing if it was an omitted separator.
                             match f(self) {
                                 Ok(t) => {
+                                    // Parsed successfully, therefore most probably the code only
+                                    // misses a separator.
+                                    expect_err
+                                        .span_suggestion_short(
+                                            sp,
+                                            &format!("missing `{}`", token_str),
+                                            token_str,
+                                            Applicability::MaybeIncorrect,
+                                        )
+                                        .emit();
+
                                     v.push(t);
                                     continue;
                                 },
                                 Err(mut e) => {
+                                    // Parsing failed, therefore it must be something more serious
+                                    // than just a missing separator.
+                                    expect_err.emit();
+
                                     e.cancel();
                                     break;
                                 }
diff --git a/src/test/ui/on-unimplemented/expected-comma-found-token.stderr b/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
index 738bf7c6c6b..2e1d484e05a 100644
--- a/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
+++ b/src/test/ui/on-unimplemented/expected-comma-found-token.stderr
@@ -2,7 +2,10 @@ error: expected one of `)` or `,`, found `label`
   --> $DIR/expected-comma-found-token.rs:9:5
    |
 LL |     message="the message"
-   |                          - expected one of `)` or `,`
+   |                          -
+   |                          |
+   |                          expected one of `)` or `,`
+   |                          help: missing `,`
 LL |     label="the label"
    |     ^^^^^ unexpected token
 
diff --git a/src/test/ui/parser/pat-lt-bracket-6.stderr b/src/test/ui/parser/pat-lt-bracket-6.stderr
index cb8bf62a8fe..fe9603cb57f 100644
--- a/src/test/ui/parser/pat-lt-bracket-6.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-6.stderr
@@ -2,7 +2,10 @@ error: expected one of `)`, `,`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-6.rs:5:19
    |
 LL |     let Test(&desc[..]) = x;
-   |                   ^ expected one of `)`, `,`, `@`, or `|`
+   |                   ^
+   |                   |
+   |                   expected one of `)`, `,`, `@`, or `|`
+   |                   help: missing `,`
 
 error[E0658]: subslice patterns are unstable
   --> $DIR/pat-lt-bracket-6.rs:5:20
diff --git a/src/test/ui/parser/pat-lt-bracket-7.stderr b/src/test/ui/parser/pat-lt-bracket-7.stderr
index aa115659d47..004dcfb2a7b 100644
--- a/src/test/ui/parser/pat-lt-bracket-7.stderr
+++ b/src/test/ui/parser/pat-lt-bracket-7.stderr
@@ -2,7 +2,10 @@ error: expected one of `)`, `,`, `@`, or `|`, found `[`
   --> $DIR/pat-lt-bracket-7.rs:5:16
    |
 LL |     for Thing(x[]) in foo {}
-   |                ^ expected one of `)`, `,`, `@`, or `|`
+   |                ^
+   |                |
+   |                expected one of `)`, `,`, `@`, or `|`
+   |                help: missing `,`
 
 error[E0308]: mismatched types
   --> $DIR/pat-lt-bracket-7.rs:9:30
diff --git a/src/test/ui/parser/recover-enum.rs b/src/test/ui/parser/recover-enum.rs
index 331bfff84f1..08dd939e2c0 100644
--- a/src/test/ui/parser/recover-enum.rs
+++ b/src/test/ui/parser/recover-enum.rs
@@ -1,11 +1,11 @@
 fn main() {
     enum Test {
-        Very
-        //~^ ERROR missing comma
-        Bad(usize)
-        //~^ ERROR missing comma
-        Stuff { a: usize }
-        //~^ ERROR missing comma
+        Very //~ HELP missing `,`
+        Bad(usize) //~ HELP missing `,`
+        //~^ ERROR expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
+        Stuff { a: usize } //~ HELP missing `,`
+        //~^ ERROR expected one of `,`, `=`, or `}`, found `Stuff`
         Here
+        //~^ ERROR expected one of `,`, `=`, or `}`, found `Here`
     }
 }
diff --git a/src/test/ui/parser/recover-enum.stderr b/src/test/ui/parser/recover-enum.stderr
index 81c7ae337db..a2b650e4f4e 100644
--- a/src/test/ui/parser/recover-enum.stderr
+++ b/src/test/ui/parser/recover-enum.stderr
@@ -1,20 +1,37 @@
-error: missing comma
-  --> $DIR/recover-enum.rs:3:13
+error: expected one of `(`, `,`, `=`, `{`, or `}`, found `Bad`
+  --> $DIR/recover-enum.rs:4:9
    |
 LL |         Very
-   |             ^ help: missing comma
+   |             -
+   |             |
+   |             expected one of `(`, `,`, `=`, `{`, or `}`
+   |             help: missing `,`
+LL |         Bad(usize)
+   |         ^^^ unexpected token
 
-error: missing comma
-  --> $DIR/recover-enum.rs:5:19
+error: expected one of `,`, `=`, or `}`, found `Stuff`
+  --> $DIR/recover-enum.rs:6:9
    |
 LL |         Bad(usize)
-   |                   ^ help: missing comma
+   |                   -
+   |                   |
+   |                   expected one of `,`, `=`, or `}`
+   |                   help: missing `,`
+LL |
+LL |         Stuff { a: usize }
+   |         ^^^^^ unexpected token
 
-error: missing comma
-  --> $DIR/recover-enum.rs:7:27
+error: expected one of `,`, `=`, or `}`, found `Here`
+  --> $DIR/recover-enum.rs:8:9
    |
 LL |         Stuff { a: usize }
-   |                           ^ help: missing comma
+   |                           -
+   |                           |
+   |                           expected one of `,`, `=`, or `}`
+   |                           help: missing `,`
+LL |
+LL |         Here
+   |         ^^^^ unexpected token
 
 error: aborting due to 3 previous errors
 
diff --git a/src/test/ui/similar-tokens.stderr b/src/test/ui/similar-tokens.stderr
index d3d5b4a6d1e..35a2fe79d5e 100644
--- a/src/test/ui/similar-tokens.stderr
+++ b/src/test/ui/similar-tokens.stderr
@@ -2,7 +2,10 @@ error: expected one of `,`, `::`, `as`, or `}`, found `.`
   --> $DIR/similar-tokens.rs:7:10
    |
 LL | use x::{A. B};
-   |          ^ expected one of `,`, `::`, `as`, or `}`
+   |          ^
+   |          |
+   |          expected one of `,`, `::`, `as`, or `}`
+   |          help: missing `,`
 
 error: aborting due to previous error
 
diff --git a/src/test/ui/tuple/tuple-struct-fields/test.stderr b/src/test/ui/tuple/tuple-struct-fields/test.stderr
index 94f39f3b9f1..bfa0b32fd45 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test.stderr
@@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test.rs:4:26
    |
 LL |     struct S2(pub((foo)) ());
-   |                          ^ expected one of `)` or `,`
+   |                         -^ expected one of `)` or `,`
+   |                         |
+   |                         help: missing `,`
 
 error[E0412]: cannot find type `foo` in this scope
   --> $DIR/test.rs:4:20
diff --git a/src/test/ui/tuple/tuple-struct-fields/test2.stderr b/src/test/ui/tuple/tuple-struct-fields/test2.stderr
index 9a64ed97ae1..d924c351439 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test2.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test2.stderr
@@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test2.rs:5:26
    |
 LL |         struct S3(pub $t ());
-   |                          ^ expected one of `)` or `,`
+   |                         -^ expected one of `)` or `,`
+   |                         |
+   |                         help: missing `,`
 ...
 LL |     define_struct! { (foo) }
    |     ------------------------ in this macro invocation
diff --git a/src/test/ui/tuple/tuple-struct-fields/test3.stderr b/src/test/ui/tuple/tuple-struct-fields/test3.stderr
index 89ae784882d..50cac6c179e 100644
--- a/src/test/ui/tuple/tuple-struct-fields/test3.stderr
+++ b/src/test/ui/tuple/tuple-struct-fields/test3.stderr
@@ -2,7 +2,9 @@ error: expected one of `)` or `,`, found `(`
   --> $DIR/test3.rs:5:27
    |
 LL |         struct S3(pub($t) ());
-   |                           ^ expected one of `)` or `,`
+   |                          -^ expected one of `)` or `,`
+   |                          |
+   |                          help: missing `,`
 ...
 LL |     define_struct! { foo }
    |     ---------------------- in this macro invocation