about summary refs log tree commit diff
diff options
context:
space:
mode:
authorMazdak Farrokhzad <twingoow@gmail.com>2019-12-03 11:36:40 +0100
committerMazdak Farrokhzad <twingoow@gmail.com>2019-12-20 22:41:29 +0100
commit9cb2b08a5d9f458fdcb20ae38bace2a49e7759ff (patch)
tree33aea1e3950212fefdbf59f909fbd44dc84cd372
parent0c32ee17815ee2ba77e44045f89c19a46580c785 (diff)
downloadrust-9cb2b08a5d9f458fdcb20ae38bace2a49e7759ff.tar.gz
rust-9cb2b08a5d9f458fdcb20ae38bace2a49e7759ff.zip
extract parse_tuple_parens_expr
-rw-r--r--src/librustc_parse/parser/expr.rs65
1 files changed, 31 insertions, 34 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs
index 1033a815985..29778b73d4a 100644
--- a/src/librustc_parse/parser/expr.rs
+++ b/src/librustc_parse/parser/expr.rs
@@ -834,9 +834,7 @@ impl<'a> Parser<'a> {
                         hi = self.prev_span;
                         ex = ExprKind::Lit(literal);
                     }
-                    None => {
-                        return Err(self.expected_expression_found());
-                    }
+                    None => return Err(self.expected_expression_found()),
                 }
             }
         }
@@ -846,37 +844,8 @@ impl<'a> Parser<'a> {
             // This match arm is a special-case of the `_` match arm below and
             // could be removed without changing functionality, but it's faster
             // to have it here, especially for programs with large constants.
-            token::Literal(_) => {
-                parse_lit!()
-            }
-            token::OpenDelim(token::Paren) => {
-                let mut first = true;
-                let parse_leading_attr_expr = |this: &mut Parser<'a>| {
-                    if first {
-                        attrs.extend(this.parse_inner_attributes()?);
-                        first = false;
-                    }
-                    this.parse_expr_catch_underscore()
-                };
-
-                // (e) is parenthesized e
-                // (e,) is a tuple with only one field, e
-                let (es, trailing_comma) =
-                    match self.parse_paren_comma_seq(parse_leading_attr_expr)
-                {
-                    Ok(x) => x,
-                    Err(err) => return Ok(
-                        self.recover_seq_parse_error(token::Paren, lo, Err(err)),
-                    ),
-                };
-
-                hi = self.prev_span;
-                ex = if es.len() == 1 && !trailing_comma {
-                    ExprKind::Paren(es.into_iter().nth(0).unwrap())
-                } else {
-                    ExprKind::Tup(es)
-                };
-            }
+            token::Literal(_) => parse_lit!(),
+            token::OpenDelim(token::Paren) => return self.parse_tuple_parens_expr(),
             token::OpenDelim(token::Brace) => {
                 return self.parse_block_expr(None, lo, BlockCheckMode::Default, attrs);
             }
@@ -1095,6 +1064,34 @@ impl<'a> Parser<'a> {
         self.maybe_recover_from_bad_qpath(expr, true)
     }
 
+    fn parse_tuple_parens_expr(&mut self) -> PResult<'a, P<Expr>> {
+        let lo = self.token.span;
+        let mut first = true;
+        let mut attrs = ThinVec::new();
+        let parse_leading_attr_expr = |p: &mut Self| {
+            if first {
+                // `(#![foo] a, b, ...)` is OK...
+                attrs = p.parse_inner_attributes()?.into();
+                // ...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) {
+            Ok(x) => x,
+            Err(err) => return Ok(self.recover_seq_parse_error(token::Paren, lo, Err(err))),
+        };
+        let kind = if es.len() == 1 && !trailing_comma {
+            // `(e)` is parenthesized `e`.
+            ExprKind::Paren(es.into_iter().nth(0).unwrap())
+        } else {
+            // `(e,)` is a tuple with only one field, `e`.
+            ExprKind::Tup(es)
+        };
+        let expr = self.mk_expr(lo.to(self.prev_span), kind, attrs);
+        self.maybe_recover_from_bad_qpath(expr, true)
+    }
+
     /// Returns a string literal if the next token is a string literal.
     /// In case of error returns `Some(lit)` if the next token is a literal with a wrong kind,
     /// and returns `None` if the next token is not literal at all.