From: Esteban Küber Date: Thu, 16 May 2019 02:59:56 +0000 (-0700) Subject: Split parser logic to its own method X-Git-Url: https://git.lizzy.rs/?a=commitdiff_plain;h=ee02661474abad0c91b8031c920904ab14f30c7e;p=rust.git Split parser logic to its own method --- diff --git a/src/libsyntax/parse/parser.rs b/src/libsyntax/parse/parser.rs index 55e13ef00dc..83bfd93d066 100644 --- a/src/libsyntax/parse/parser.rs +++ b/src/libsyntax/parse/parser.rs @@ -2630,93 +2630,9 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { return Err(db); } else if self.span.rust_2018() && self.eat_keyword(keywords::Await) { let await_sp = self.prev_span; - match self.token { - token::Not => { - // FIXME: make this an error when `await!` is no longer supported - // https://github.com/rust-lang/rust/issues/60610 - self.expect(&token::Not)?; - self.expect(&token::OpenDelim(token::Paren))?; - let expr = self.parse_expr().map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this await macro call", - ); - err - })?; - self.expect(&token::CloseDelim(token::Paren))?; - ex = ExprKind::Await(ast::AwaitOrigin::MacroLike, expr); - } - token::Question => { - // Handle `await? ` - self.bump(); // `?` - let expr = self.parse_expr().map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this incorrect await statement", - ); - err - })?; - let sp = lo.to(expr.span); - let expr_str = self.sess.source_map().span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - let expr = self.mk_expr( - sp, - ExprKind::Await(ast::AwaitOrigin::FieldLike, expr), - ThinVec::new(), - ); - hi = sp; - ex = ExprKind::Try(expr); - let mut err = self.struct_span_err( - await_sp, - "incorrect use of `await`", - ); - err.span_suggestion( - sp, - "`await` is not a statement", - format!("{}.await?", expr_str), - Applicability::MachineApplicable, - ); - err.emit(); - } - ref t => { - // Handle `await ` - let expr = if t == &token::OpenDelim(token::Brace) { - // Handle `await { }` - // this needs to be handled separatedly from the next arm to avoid - // interpreting `await { }?` as `?.await` - self.parse_block_expr( - None, - self.span, - BlockCheckMode::Default, - ThinVec::new(), - ) - } else { - self.parse_expr() - }.map_err(|mut err| { - err.span_label( - await_sp, - "while parsing this incorrect await statement", - ); - err - })?; - let expr_str = self.sess.source_map().span_to_snippet(expr.span) - .unwrap_or_else(|_| pprust::expr_to_string(&expr)); - let sp = lo.to(expr.span); - hi = sp; - ex = ExprKind::Await(ast::AwaitOrigin::FieldLike, expr); - let mut err = self.struct_span_err( - await_sp, - "incorrect use of `await`", - ); - err.span_suggestion( - sp, - "`await` is not a statement", - format!("{}.await", expr_str), - Applicability::MachineApplicable, - ); - err.emit(); - } - } + let e = self.parse_async_macro_or_stmt(lo, await_sp)?; + hi = e.0; + ex = e.1; } else if self.token.is_path_start() { let path = self.parse_path(PathStyle::Expr)?; @@ -2781,6 +2697,99 @@ fn parse_bottom_expr(&mut self) -> PResult<'a, P> { self.maybe_recover_from_bad_qpath(expr, true) } + fn parse_async_macro_or_stmt( + &mut self, + lo: Span, + await_sp: Span, + ) -> PResult<'a, (Span, ExprKind)> { + Ok(match self.token { + token::Not => { + // Handle correct `await!()` + // FIXME: make this an error when `await!` is no longer supported + // https://github.com/rust-lang/rust/issues/60610 + self.expect(&token::Not)?; + self.expect(&token::OpenDelim(token::Paren))?; + let expr = self.parse_expr().map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this await macro call", + ); + err + })?; + self.expect(&token::CloseDelim(token::Paren))?; + (expr.span, ExprKind::Await(ast::AwaitOrigin::MacroLike, expr)) + } + token::Question => { + // Handle `await? ` + self.bump(); // `?` + let expr = self.parse_expr().map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this incorrect await statement", + ); + err + })?; + let sp = lo.to(expr.span); + let expr_str = self.sess.source_map().span_to_snippet(expr.span) + .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let expr = self.mk_expr( + sp, + ExprKind::Await(ast::AwaitOrigin::FieldLike, expr), + ThinVec::new(), + ); + let mut err = self.struct_span_err( + await_sp, + "incorrect use of `await`", + ); + err.span_suggestion( + sp, + "`await` is not a statement", + format!("{}.await?", expr_str), + Applicability::MachineApplicable, + ); + err.emit(); + (sp, ExprKind::Try(expr)) + } + ref t => { + // Handle `await ` + let expr = if t == &token::OpenDelim(token::Brace) { + // Handle `await { }` + // this needs to be handled separatedly from the next arm to avoid + // interpreting `await { }?` as `?.await` + self.parse_block_expr( + None, + self.span, + BlockCheckMode::Default, + ThinVec::new(), + ) + } else { + self.parse_expr() + }.map_err(|mut err| { + err.span_label( + await_sp, + "while parsing this incorrect await statement", + ); + err + })?; + let expr_str = self.sess.source_map().span_to_snippet(expr.span) + .unwrap_or_else(|_| pprust::expr_to_string(&expr)); + let sp = lo.to(expr.span); + let mut err = self.struct_span_err( + await_sp, + "incorrect use of `await`", + ); + err.span_suggestion( + sp, + "`await` is not a statement", + format!("{}.await", expr_str), + Applicability::MachineApplicable, + ); + err.emit(); + (sp, ExprKind::Await(ast::AwaitOrigin::FieldLike, expr)) + } + }) + } + fn maybe_parse_struct_expr( &mut self, lo: Span,