]> git.lizzy.rs Git - rust.git/commitdiff
Clean up `parse_bottom_expr`
authorA C <achan1989@gmail.com>
Mon, 16 Sep 2019 20:45:43 +0000 (21:45 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Fri, 20 Dec 2019 21:41:29 +0000 (22:41 +0100)
src/librustc_parse/parser/expr.rs

index 7af9b7267a87f92ef6947ce0f1e9f1b3202162b4..1033a815985f56a8695421c3b895097b3438344e 100644 (file)
@@ -91,24 +91,29 @@ pub fn parse_expr(&mut self) -> PResult<'a, P<Expr>> {
         self.parse_expr_res(Restrictions::empty(), None)
     }
 
+    fn parse_expr_catch_underscore(&mut self) -> PResult<'a, P<Expr>> {
+        match self.parse_expr() {
+            Ok(expr) => Ok(expr),
+            Err(mut err) => match self.token.kind {
+                token::Ident(name, false)
+                if name == kw::Underscore && self.look_ahead(1, |t| {
+                    t == &token::Comma
+                }) => {
+                    // Special-case handling of `foo(_, _, _)`
+                    err.emit();
+                    let sp = self.token.span;
+                    self.bump();
+                    Ok(self.mk_expr(sp, ExprKind::Err, ThinVec::new()))
+                }
+                _ => Err(err),
+            },
+        }
+    }
+
+    /// Parses a sequence of expressions bounded by parentheses.
     fn parse_paren_expr_seq(&mut self) -> PResult<'a, Vec<P<Expr>>> {
         self.parse_paren_comma_seq(|p| {
-            match p.parse_expr() {
-                Ok(expr) => Ok(expr),
-                Err(mut err) => match p.token.kind {
-                    token::Ident(name, false)
-                    if name == kw::Underscore && p.look_ahead(1, |t| {
-                        t == &token::Comma
-                    }) => {
-                        // Special-case handling of `foo(_, _, _)`
-                        err.emit();
-                        let sp = p.token.span;
-                        p.bump();
-                        Ok(p.mk_expr(sp, ExprKind::Err, ThinVec::new()))
-                    }
-                    _ => Err(err),
-                },
-            }
+            p.parse_expr_catch_underscore()
         }).map(|(r, _)| r)
     }
 
@@ -845,51 +850,25 @@ macro_rules! parse_lit {
                 parse_lit!()
             }
             token::OpenDelim(token::Paren) => {
-                self.bump();
-
-                attrs.extend(self.parse_inner_attributes()?);
-
-                // `(e)` is parenthesized `e`.
-                // `(e,)` is a tuple with only one field, `e`.
-                let mut es = vec![];
-                let mut trailing_comma = false;
-                let mut recovered = false;
-                while self.token != token::CloseDelim(token::Paren) {
-                    es.push(match self.parse_expr() {
-                        Ok(es) => es,
-                        Err(mut err) => {
-                            // Recover from parse error in tuple list.
-                            match self.token.kind {
-                                token::Ident(name, false)
-                                if name == kw::Underscore && self.look_ahead(1, |t| {
-                                    t == &token::Comma
-                                }) => {
-                                    // Special-case handling of `Foo<(_, _, _)>`
-                                    err.emit();
-                                    let sp = self.token.span;
-                                    self.bump();
-                                    self.mk_expr(sp, ExprKind::Err, ThinVec::new())
-                                }
-                                _ => return Ok(
-                                    self.recover_seq_parse_error(token::Paren, lo, Err(err)),
-                                ),
-                            }
-                        }
-                    });
-                    recovered = self.expect_one_of(
-                        &[],
-                        &[token::Comma, token::CloseDelim(token::Paren)],
-                    )?;
-                    if self.eat(&token::Comma) {
-                        trailing_comma = true;
-                    } else {
-                        trailing_comma = false;
-                        break;
+                let mut first = true;
+                let parse_leading_attr_expr = |this: &mut Parser<'a>| {
+                    if first {
+                        attrs.extend(this.parse_inner_attributes()?);
+                        first = false;
                     }
-                }
-                if !recovered {
-                    self.bump();
-                }
+                    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 {