diff options
| author | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-03 14:01:24 +0100 |
|---|---|---|
| committer | Mazdak Farrokhzad <twingoow@gmail.com> | 2019-12-20 22:41:29 +0100 |
| commit | 2f9b191886457f16876fe9ef08369f8d0774e200 (patch) | |
| tree | 73c74e3ace3b016a57e037ded260bd973970d19e | |
| parent | 327641e35c10624e7c728fce269885c6e4f6a602 (diff) | |
| download | rust-2f9b191886457f16876fe9ef08369f8d0774e200.tar.gz rust-2f9b191886457f16876fe9ef08369f8d0774e200.zip | |
extract parse_{expr_opt, return_expr, yield_expr}
| -rw-r--r-- | src/librustc_parse/parser/expr.rs | 65 |
1 files changed, 34 insertions, 31 deletions
diff --git a/src/librustc_parse/parser/expr.rs b/src/librustc_parse/parser/expr.rs index 292d277a678..ea96143f4e8 100644 --- a/src/librustc_parse/parser/expr.rs +++ b/src/librustc_parse/parser/expr.rs @@ -823,24 +823,18 @@ impl<'a> Parser<'a> { 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 @@ impl<'a> Parser<'a> { }; } 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 @@ impl<'a> Parser<'a> { } 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 @@ impl<'a> Parser<'a> { parse_lit!() } } - } + }; let expr = self.mk_expr(lo.to(hi), ex, attrs); self.maybe_recover_from_bad_qpath(expr, true) @@ -1116,6 +1092,33 @@ impl<'a> Parser<'a> { 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. |
