@@ -2629,10 +2629,9 @@ impl<'a> Parser<'a> {
26292629 db. note ( "variable declaration using `let` is a statement" ) ;
26302630 return Err ( db) ;
26312631 } else if self . span . rust_2018 ( ) && self . eat_keyword ( keywords:: Await ) {
2632- let await_sp = self . prev_span ;
2633- let e = self . parse_async_macro_or_stmt ( lo, await_sp) ?;
2634- hi = e. 0 ;
2635- ex = e. 1 ;
2632+ let ( await_hi, e_kind) = self . parse_await_macro_or_alt ( lo, self . prev_span ) ?;
2633+ hi = await_hi;
2634+ ex = e_kind;
26362635 } else if self . token . is_path_start ( ) {
26372636 let path = self . parse_path ( PathStyle :: Expr ) ?;
26382637
@@ -2697,97 +2696,29 @@ impl<'a> Parser<'a> {
26972696 self . maybe_recover_from_bad_qpath ( expr, true )
26982697 }
26992698
2700- fn parse_async_macro_or_stmt (
2699+ /// Parse `await!(<expr>)` calls, or alternatively recover from incorrect but reasonable
2700+ /// alternative syntaxes `await <expr>`, `await? <expr>`, `await(<expr>)` and
2701+ /// `await { <expr> }`.
2702+ fn parse_await_macro_or_alt (
27012703 & mut self ,
27022704 lo : Span ,
27032705 await_sp : Span ,
27042706 ) -> PResult < ' a , ( Span , ExprKind ) > {
2705- Ok ( match self . token {
2706- token:: Not => {
2707- // Handle correct `await!(<expr>)`
2708- // FIXME: make this an error when `await!` is no longer supported
2709- // https://github.com/rust-lang/rust/issues/60610
2710- self . expect ( & token:: Not ) ?;
2711- self . expect ( & token:: OpenDelim ( token:: Paren ) ) ?;
2712- let expr = self . parse_expr ( ) . map_err ( |mut err| {
2713- err. span_label (
2714- await_sp,
2715- "while parsing this await macro call" ,
2716- ) ;
2717- err
2718- } ) ?;
2719- self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
2720- ( expr. span , ExprKind :: Await ( ast:: AwaitOrigin :: MacroLike , expr) )
2721- }
2722- token:: Question => {
2723- // Handle `await? <expr>`
2724- self . bump ( ) ; // `?`
2725- let expr = self . parse_expr ( ) . map_err ( |mut err| {
2726- err. span_label (
2727- await_sp,
2728- "while parsing this incorrect await statement" ,
2729- ) ;
2730- err
2731- } ) ?;
2732- let sp = lo. to ( expr. span ) ;
2733- let expr_str = self . sess . source_map ( ) . span_to_snippet ( expr. span )
2734- . unwrap_or_else ( |_| pprust:: expr_to_string ( & expr) ) ;
2735- let expr = self . mk_expr (
2736- sp,
2737- ExprKind :: Await ( ast:: AwaitOrigin :: FieldLike , expr) ,
2738- ThinVec :: new ( ) ,
2739- ) ;
2740- let mut err = self . struct_span_err (
2741- sp,
2742- "incorrect use of `await`" ,
2743- ) ;
2744- err. span_suggestion (
2745- sp,
2746- "`await` is not a statement" ,
2747- format ! ( "{}.await?" , expr_str) ,
2748- Applicability :: MachineApplicable ,
2749- ) ;
2750- err. emit ( ) ;
2751- ( sp, ExprKind :: Try ( expr) )
2752- }
2753- ref t => {
2754- // Handle `await <expr>`
2755- let expr = if t == & token:: OpenDelim ( token:: Brace ) {
2756- // Handle `await { <expr> }`
2757- // this needs to be handled separatedly from the next arm to avoid
2758- // interpreting `await { <expr> }?` as `<expr>?.await`
2759- self . parse_block_expr (
2760- None ,
2761- self . span ,
2762- BlockCheckMode :: Default ,
2763- ThinVec :: new ( ) ,
2764- )
2765- } else {
2766- self . parse_expr ( )
2767- } . map_err ( |mut err| {
2768- err. span_label (
2769- await_sp,
2770- "while parsing this incorrect await statement" ,
2771- ) ;
2772- err
2773- } ) ?;
2774- let expr_str = self . sess . source_map ( ) . span_to_snippet ( expr. span )
2775- . unwrap_or_else ( |_| pprust:: expr_to_string ( & expr) ) ;
2776- let sp = lo. to ( expr. span ) ;
2777- let mut err = self . struct_span_err (
2778- sp,
2779- "incorrect use of `await`" ,
2780- ) ;
2781- err. span_suggestion (
2782- sp,
2783- "`await` is not a statement" ,
2784- format ! ( "{}.await" , expr_str) ,
2785- Applicability :: MachineApplicable ,
2786- ) ;
2787- err. emit ( ) ;
2788- ( sp, ExprKind :: Await ( ast:: AwaitOrigin :: FieldLike , expr) )
2789- }
2790- } )
2707+ if self . token == token:: Not {
2708+ // Handle correct `await!(<expr>)`.
2709+ // FIXME: make this an error when `await!` is no longer supported
2710+ // https://github.com/rust-lang/rust/issues/60610
2711+ self . expect ( & token:: Not ) ?;
2712+ self . expect ( & token:: OpenDelim ( token:: Paren ) ) ?;
2713+ let expr = self . parse_expr ( ) . map_err ( |mut err| {
2714+ err. span_label ( await_sp, "while parsing this await macro call" ) ;
2715+ err
2716+ } ) ?;
2717+ self . expect ( & token:: CloseDelim ( token:: Paren ) ) ?;
2718+ Ok ( ( expr. span , ExprKind :: Await ( ast:: AwaitOrigin :: MacroLike , expr) ) )
2719+ } else { // Handle `await <expr>`.
2720+ self . parse_incorrect_await_syntax ( lo, await_sp)
2721+ }
27912722 }
27922723
27932724 fn maybe_parse_struct_expr (
@@ -2938,10 +2869,13 @@ impl<'a> Parser<'a> {
29382869 }
29392870
29402871 /// Parses a block or unsafe block.
2941- fn parse_block_expr ( & mut self , opt_label : Option < Label > ,
2942- lo : Span , blk_mode : BlockCheckMode ,
2943- outer_attrs : ThinVec < Attribute > )
2944- -> PResult < ' a , P < Expr > > {
2872+ crate fn parse_block_expr (
2873+ & mut self ,
2874+ opt_label : Option < Label > ,
2875+ lo : Span ,
2876+ blk_mode : BlockCheckMode ,
2877+ outer_attrs : ThinVec < Attribute > ,
2878+ ) -> PResult < ' a , P < Expr > > {
29452879 self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
29462880
29472881 let mut attrs = outer_attrs;
0 commit comments