]> git.lizzy.rs Git - rust.git/commitdiff
Refactor 'parse_enum_item' to use 'parse_delim_comma_seq'
authorJanusz Marcinkiewicz <virrages@gmail.com>
Sun, 24 Nov 2019 21:33:00 +0000 (22:33 +0100)
committerJanusz Marcinkiewicz <virrages@gmail.com>
Tue, 26 Nov 2019 18:24:36 +0000 (19:24 +0100)
src/librustc_parse/parser/item.rs
src/librustc_parse/parser/mod.rs
src/test/ui/on-unimplemented/expected-comma-found-token.stderr
src/test/ui/parser/pat-lt-bracket-6.stderr
src/test/ui/parser/pat-lt-bracket-7.stderr
src/test/ui/parser/recover-enum.rs
src/test/ui/parser/recover-enum.stderr
src/test/ui/similar-tokens.stderr
src/test/ui/tuple/tuple-struct-fields/test.stderr
src/test/ui/tuple/tuple-struct-fields/test2.stderr
src/test/ui/tuple/tuple-struct-fields/test3.stderr

index 2c9d4004226c74b5c9a853850db244e2ee128add..7569269921a8cd894deb3a3ea1776228f8fb353e 100644 (file)
@@ -7,7 +7,7 @@
 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 @@ fn parse_item_enum(&mut self) -> PResult<'a, ItemInfo> {
         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 @@ fn recover_nested_adt_item(&mut self, keyword: Symbol) -> PResult<'a, bool> {
             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,
index d810117662c655c0c60287f479957efd69e67181..ea7673767d07e811e76077eff81625edae754093 100644 (file)
@@ -805,21 +805,39 @@ fn parse_seq_to_before_tokens<T>(
                             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;
                                 }
index 738bf7c6c6ba0e60d70a78e25784d878c8f5dac3..2e1d484e05a5a4d8fa670382efda5fee6b1531a4 100644 (file)
@@ -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
 
index cb8bf62a8fe0b4168f8e7b8495064bff7dc991a7..fe9603cb57f1f094905a57f57ec4179dece68ffb 100644 (file)
@@ -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
index aa115659d47a4cc67123a7faff4e81c1768616e5..004dcfb2a7b2d0a9ce63225583cf611a968d4ecf 100644 (file)
@@ -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
index 331bfff84f106a778f7f68cf6bfc5aa2d345b6c0..08dd939e2c023f7f3290a796d02f4bc9e005b1cb 100644 (file)
@@ -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`
     }
 }
index 81c7ae337dbebe0c12e91256032adaaa52691634..a2b650e4f4eb7ca23d98d19a226fb8a8b90fd8ca 100644 (file)
@@ -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
 
index d3d5b4a6d1e7db7cbbf1be02ed71d4da8213eb51..35a2fe79d5e66e380eaf1f833ae1465308058d28 100644 (file)
@@ -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
 
index 94f39f3b9f1dde107f44c14aeeb3d2004452de43..bfa0b32fd458ae0063871d32b819b2b02586343f 100644 (file)
@@ -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
index 9a64ed97ae1d4c6ee3755a8327cbc23e93b4c0d0..d924c351439bd91749108bc8634598674eee7789 100644 (file)
@@ -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
index 89ae784882d4de97b3e6aa2c0d04f0eb065a1ec2..50cac6c179e31a29fa9f8fd22cbcac3e5f7262a3 100644 (file)
@@ -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