@@ -2629,10 +2629,9 @@ impl<'a> Parser<'a> {
2629
2629
db. note ( "variable declaration using `let` is a statement" ) ;
2630
2630
return Err ( db) ;
2631
2631
} 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;
2636
2635
} else if self . token . is_path_start ( ) {
2637
2636
let path = self . parse_path ( PathStyle :: Expr ) ?;
2638
2637
@@ -2697,97 +2696,29 @@ impl<'a> Parser<'a> {
2697
2696
self . maybe_recover_from_bad_qpath ( expr, true )
2698
2697
}
2699
2698
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 (
2701
2703
& mut self ,
2702
2704
lo : Span ,
2703
2705
await_sp : Span ,
2704
2706
) -> 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
+ }
2791
2722
}
2792
2723
2793
2724
fn maybe_parse_struct_expr (
@@ -2938,10 +2869,13 @@ impl<'a> Parser<'a> {
2938
2869
}
2939
2870
2940
2871
/// 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 > > {
2945
2879
self . expect ( & token:: OpenDelim ( token:: Brace ) ) ?;
2946
2880
2947
2881
let mut attrs = outer_attrs;
0 commit comments