]> git.lizzy.rs Git - rust.git/commitdiff
extract parse_{expr_opt, return_expr, yield_expr}
authorMazdak Farrokhzad <twingoow@gmail.com>
Tue, 3 Dec 2019 13:01:24 +0000 (14:01 +0100)
committerMazdak Farrokhzad <twingoow@gmail.com>
Fri, 20 Dec 2019 21:41:29 +0000 (22:41 +0100)
src/librustc_parse/parser/expr.rs

index 292d277a6786316935153516ea544afc9db33fb5..ea96143f4e87759ccd32c8b61efa18922ffe4c68 100644 (file)
@@ -823,24 +823,18 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P<Expr>> {
         let attrs = ThinVec::new();
 
         let lo = self.token.span;
-        let mut hi = self.token.span;
-
-        let ex: ExprKind;
 
         macro_rules! parse_lit {
             () => {
                 match self.parse_opt_lit() {
-                    Some(literal) => {
-                        hi = self.prev_span;
-                        ex = ExprKind::Lit(literal);
-                    }
+                    Some(literal) => (self.prev_span, ExprKind::Lit(literal)),
                     None => return Err(self.expected_expression_found()),
                 }
             }
         }
 
         // Note: when adding new syntax here, don't forget to adjust `TokenKind::can_begin_expr()`.
-        match self.token.kind {
+        let (hi, ex) = match self.token.kind {
             // 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.
@@ -911,13 +905,7 @@ macro_rules! parse_lit {
                     };
                 }
                 if self.eat_keyword(kw::Return) {
-                    if self.token.can_begin_expr() {
-                        let e = self.parse_expr()?;
-                        hi = e.span;
-                        ex = ExprKind::Ret(Some(e));
-                    } else {
-                        ex = ExprKind::Ret(None);
-                    }
+                    return self.parse_return_expr(attrs);
                 } else if self.eat_keyword(kw::Break) {
                     let label = self.eat_label();
                     let e = if self.token.can_begin_expr()
@@ -928,25 +916,13 @@ macro_rules! parse_lit {
                     } else {
                         None
                     };
-                    ex = ExprKind::Break(label, e);
-                    hi = self.prev_span;
+                    (self.prev_span, ExprKind::Break(label, e))
                 } else if self.eat_keyword(kw::Yield) {
-                    if self.token.can_begin_expr() {
-                        let e = self.parse_expr()?;
-                        hi = e.span;
-                        ex = ExprKind::Yield(Some(e));
-                    } else {
-                        ex = ExprKind::Yield(None);
-                    }
-
-                    let span = lo.to(hi);
-                    self.sess.gated_spans.gate(sym::generators, span);
+                    return self.parse_yield_expr(attrs);
                 } else if self.eat_keyword(kw::Let) {
                     return self.parse_let_expr(attrs);
                 } else if is_span_rust_2018 && self.eat_keyword(kw::Await) {
-                    let (await_hi, e_kind) = self.parse_incorrect_await_syntax(lo, self.prev_span)?;
-                    hi = await_hi;
-                    ex = e_kind;
+                    self.parse_incorrect_await_syntax(lo, self.prev_span)?
                 } else if !self.unclosed_delims.is_empty() && self.check(&token::Semi) {
                     // Don't complain about bare semicolons after unclosed braces
                     // recovery in order to keep the error count down. Fixing the
@@ -964,7 +940,7 @@ macro_rules! parse_lit {
                     parse_lit!()
                 }
             }
-        }
+        };
 
         let expr = self.mk_expr(lo.to(hi), ex, attrs);
         self.maybe_recover_from_bad_qpath(expr, true)
@@ -1116,6 +1092,33 @@ fn recover_do_catch(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>
         self.parse_try_block(lo, attrs)
     }
 
+    /// Parse an expression if the token can begin one.
+    fn parse_expr_opt(&mut self) -> PResult<'a, Option<P<Expr>>> {
+        Ok(if self.token.can_begin_expr() {
+            Some(self.parse_expr()?)
+        } else {
+            None
+        })
+    }
+
+    /// Parse `"return" expr?`.
+    fn parse_return_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+        let lo = self.prev_span;
+        let kind = ExprKind::Ret(self.parse_expr_opt()?);
+        let expr = self.mk_expr(lo.to(self.prev_span), kind, attrs);
+        self.maybe_recover_from_bad_qpath(expr, true)
+    }
+
+    /// Parse `"yield" expr?`.
+    fn parse_yield_expr(&mut self, attrs: ThinVec<Attribute>) -> PResult<'a, P<Expr>> {
+        let lo = self.prev_span;
+        let kind = ExprKind::Yield(self.parse_expr_opt()?);
+        let span = lo.to(self.prev_span);
+        self.sess.gated_spans.gate(sym::generators, span);
+        let expr = self.mk_expr(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.