about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-04 10:13:29 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2019-12-20 22:53:40 +0100
commit9b53c5be0607d0c1e9aee357a309491ee1e99c80 (patch)
treec3374e7e6ceeb86012c2062dc86adb03754d928e
parent66470d3217f27b5950c38a3af4a99e0ef12fa2c8 (diff)
downloadrust-9b53c5be0607d0c1e9aee357a309491ee1e99c80.tar.gz
rust-9b53c5be0607d0c1e9aee357a309491ee1e99c80.zip
fix bug in parse_tuple_parens_expr + related refactoring
-rw-r--r--src/librustc_parse/parser/attr.rs23
-rw-r--r--src/librustc_parse/parser/expr.rs32
-rw-r--r--src/librustc_parse/parser/mod.rs62
3 files changed, 49 insertions, 68 deletions
diff --git a/src/librustc_parse/parser/attr.rs b/src/librustc_parse/parser/attr.rs
index 00fd6b8a25b..51310fb88f6 100644
--- a/src/librustc_parse/parser/attr.rs
+++ b/src/librustc_parse/parser/attr.rs
@@ -1,4 +1,4 @@
-use super::{SeqSep, Parser, TokenType, PathStyle};
+use super::{Parser, TokenType, PathStyle};
 use rustc_errors::PResult;
 use syntax::attr;
 use syntax::ast;
@@ -301,8 +301,10 @@ impl<'a> Parser<'a> {
     crate fn parse_meta_item_kind(&mut self) -> PResult<'a, ast::MetaItemKind> {
         Ok(if self.eat(&token::Eq) {
             ast::MetaItemKind::NameValue(self.parse_unsuffixed_lit()?)
-        } else if self.eat(&token::OpenDelim(token::Paren)) {
-            ast::MetaItemKind::List(self.parse_meta_seq()?)
+        } else if self.check(&token::OpenDelim(token::Paren)) {
+            // Matches `meta_seq = ( COMMASEP(meta_item_inner) )`.
+            let (list, _) = self.parse_paren_comma_seq(|p| p.parse_meta_item_inner())?;
+            ast::MetaItemKind::List(list)
         } else {
             ast::MetaItemKind::Word
         })
@@ -311,16 +313,12 @@ impl<'a> Parser<'a> {
     /// Matches `meta_item_inner : (meta_item | UNSUFFIXED_LIT) ;`.
     fn parse_meta_item_inner(&mut self) -> PResult<'a, ast::NestedMetaItem> {
         match self.parse_unsuffixed_lit() {
-            Ok(lit) => {
-                return Ok(ast::NestedMetaItem::Literal(lit))
-            }
+            Ok(lit) => return Ok(ast::NestedMetaItem::Literal(lit)),
             Err(ref mut err) => err.cancel(),
         }
 
         match self.parse_meta_item() {
-            Ok(mi) => {
-                return Ok(ast::NestedMetaItem::MetaItem(mi))
-            }
+            Ok(mi) => return Ok(ast::NestedMetaItem::MetaItem(mi)),
             Err(ref mut err) => err.cancel(),
         }
 
@@ -328,11 +326,4 @@ impl<'a> Parser<'a> {
         let msg = format!("expected unsuffixed literal or identifier, found `{}`", found);
         Err(self.diagnostic().struct_span_err(self.token.span, &msg))
     }
-
-    /// Matches `meta_seq = ( COMMASEP(meta_item_inner) )`.
-    fn parse_meta_seq(&mut self) -> PResult<'a, Vec<ast::NestedMetaItem>> {
-        self.parse_seq_to_end(&token::CloseDelim(token::Paren),
-                              SeqSep::trailing_allowed(token::Comma),
-                              |p: &mut Parser<'a>| p.parse_meta_item_inner())
-    }
 }
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 68af34a36bb..8c66804604f 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -919,17 +919,13 @@ impl<'a> Parser<'a> {
 
     fn parse_tuple_parens_expr(&mut self, mut attrs: AttrVec) -> PResult<'a, P<Expr>> {
         let lo = self.token.span;
-        let mut first = true;
-        let parse_leading_attr_expr = |p: &mut Self| {
-            if first {
-                // `(#![foo] a, b, ...)` is OK...
-                attrs.extend(p.parse_inner_attributes()?);
-                // ...but not `(a, #![foo] b, ...)`.
-                first = false;
-            }
-            p.parse_expr_catch_underscore()
-        };
-        let (es, trailing_comma) = match self.parse_paren_comma_seq(parse_leading_attr_expr) {
+        self.expect(&token::OpenDelim(token::Paren))?;
+        attrs.extend(self.parse_inner_attributes()?); // `(#![foo] a, b, ...)` is OK.
+        let (es, trailing_comma) = match self.parse_seq_to_end(
+            &token::CloseDelim(token::Paren),
+            SeqSep::trailing_allowed(token::Comma),
+            |p| p.parse_expr_catch_underscore(),
+        ) {
             Ok(x) => x,
             Err(err) => return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err))),
         };
@@ -950,7 +946,8 @@ impl<'a> Parser<'a> {
 
         attrs.extend(self.parse_inner_attributes()?);
 
-        let kind = if self.eat(&token::CloseDelim(token::Bracket)) {
+        let close = &token::CloseDelim(token::Bracket);
+        let kind = if self.eat(close) {
             // Empty vector
             ExprKind::Array(Vec::new())
         } else {
@@ -962,21 +959,18 @@ impl<'a> Parser<'a> {
                     id: DUMMY_NODE_ID,
                     value: self.parse_expr()?,
                 };
-                self.expect(&token::CloseDelim(token::Bracket))?;
+                self.expect(close)?;
                 ExprKind::Repeat(first_expr, count)
             } else if self.eat(&token::Comma) {
                 // Vector with two or more elements.
-                let remaining_exprs = self.parse_seq_to_end(
-                    &token::CloseDelim(token::Bracket),
-                    SeqSep::trailing_allowed(token::Comma),
-                    |p| Ok(p.parse_expr()?)
-                )?;
+                let sep = SeqSep::trailing_allowed(token::Comma);
+                let (remaining_exprs, _) = self.parse_seq_to_end(close, sep, |p| p.parse_expr())?;
                 let mut exprs = vec![first_expr];
                 exprs.extend(remaining_exprs);
                 ExprKind::Array(exprs)
             } else {
                 // Vector with one element
-                self.expect(&token::CloseDelim(token::Bracket))?;
+                self.expect(close)?;
                 ExprKind::Array(vec![first_expr])
             }
         };
diff --git a/src/librustc_parse/parser/mod.rs b/src/librustc_parse/parser/mod.rs
index 938c2d89857..255e789b58e 100644
--- a/src/librustc_parse/parser/mod.rs
+++ b/src/librustc_parse/parser/mod.rs
@@ -739,34 +739,6 @@ impl<'a> Parser<'a> {
         }
     }
 
-    /// Parses a sequence, including the closing delimiter. The function
-    /// `f` must consume tokens until reaching the next separator or
-    /// closing bracket.
-    fn parse_seq_to_end<T>(
-        &mut self,
-        ket: &TokenKind,
-        sep: SeqSep,
-        f: impl FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
-    ) -> PResult<'a, Vec<T>> {
-        let (val, _, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
-        if !recovered {
-            self.bump();
-        }
-        Ok(val)
-    }
-
-    /// Parses a sequence, not including the closing delimiter. The function
-    /// `f` must consume tokens until reaching the next separator or
-    /// closing bracket.
-    fn parse_seq_to_before_end<T>(
-        &mut self,
-        ket: &TokenKind,
-        sep: SeqSep,
-        f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
-    ) -> PResult<'a, (Vec<T>, bool, bool)> {
-        self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
-    }
-
     fn expect_any_with_type(&mut self, kets: &[&TokenKind], expect: TokenExpectType) -> bool {
         kets.iter().any(|k| {
             match expect {
@@ -854,6 +826,34 @@ impl<'a> Parser<'a> {
         Ok((v, trailing, recovered))
     }
 
+    /// Parses a sequence, not including the closing delimiter. The function
+    /// `f` must consume tokens until reaching the next separator or
+    /// closing bracket.
+    fn parse_seq_to_before_end<T>(
+        &mut self,
+        ket: &TokenKind,
+        sep: SeqSep,
+        f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
+    ) -> PResult<'a, (Vec<T>, bool, bool)> {
+        self.parse_seq_to_before_tokens(&[ket], sep, TokenExpectType::Expect, f)
+    }
+
+    /// Parses a sequence, including the closing delimiter. The function
+    /// `f` must consume tokens until reaching the next separator or
+    /// closing bracket.
+    fn parse_seq_to_end<T>(
+        &mut self,
+        ket: &TokenKind,
+        sep: SeqSep,
+        f: impl FnMut(&mut Parser<'a>) -> PResult<'a,  T>,
+    ) -> PResult<'a, (Vec<T>, bool /* trailing */)> {
+        let (val, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
+        if !recovered {
+            self.eat(ket);
+        }
+        Ok((val, trailing))
+    }
+
     /// Parses a sequence, including the closing delimiter. The function
     /// `f` must consume tokens until reaching the next separator or
     /// closing bracket.
@@ -865,11 +865,7 @@ impl<'a> Parser<'a> {
         f: impl FnMut(&mut Parser<'a>) -> PResult<'a, T>,
     ) -> PResult<'a, (Vec<T>, bool)> {
         self.expect(bra)?;
-        let (result, trailing, recovered) = self.parse_seq_to_before_end(ket, sep, f)?;
-        if !recovered {
-            self.eat(ket);
-        }
-        Ok((result, trailing))
+        self.parse_seq_to_end(ket, sep, f)
     }
 
     fn parse_delim_comma_seq<T>(