@@ -2621,13 +2621,8 @@ impl<'a> Parser<'a> {
26212621 } else {
26222622 ex = ExprKind :: Yield ( None ) ;
26232623 }
2624- } else if self . token . is_keyword ( keywords:: Let ) {
2625- // Catch this syntax error here, instead of in `parse_ident`, so
2626- // that we can explicitly mention that let is not to be used as an expression
2627- let mut db = self . fatal ( "expected expression, found statement (`let`)" ) ;
2628- db. span_label ( self . span , "expected expression" ) ;
2629- db. note ( "variable declaration using `let` is a statement" ) ;
2630- return Err ( db) ;
2624+ } else if self . eat_keyword ( keywords:: Let ) {
2625+ return self . parse_let_expr ( attrs) ;
26312626 } else if self . span . rust_2018 ( ) && self . eat_keyword ( keywords:: Await ) {
26322627 // FIXME: remove this branch when `await!` is no longer supported
26332628 // https://github.com/rust-lang/rust/issues/60610
@@ -2886,15 +2881,13 @@ impl<'a> Parser<'a> {
28862881 attrs. extend :: < Vec < _ > > ( expr. attrs . into ( ) ) ;
28872882 expr. attrs = attrs;
28882883 match expr. node {
2889- ExprKind :: If ( ..) | ExprKind :: IfLet ( ..) => {
2890- if !expr. attrs . is_empty ( ) {
2891- // Just point to the first attribute in there...
2892- let span = expr. attrs [ 0 ] . span ;
2893-
2894- self . span_err ( span,
2895- "attributes are not yet allowed on `if` \
2896- expressions") ;
2897- }
2884+ ExprKind :: If ( ..) if !expr. attrs . is_empty ( ) => {
2885+ // Just point to the first attribute in there...
2886+ let span = expr. attrs [ 0 ] . span ;
2887+
2888+ self . span_err ( span,
2889+ "attributes are not yet allowed on `if` \
2890+ expressions") ;
28982891 }
28992892 _ => { }
29002893 }
@@ -3778,9 +3771,6 @@ impl<'a> Parser<'a> {
37783771
37793772 /// Parses an `if` or `if let` expression (`if` token already eaten).
37803773 fn parse_if_expr ( & mut self , attrs : ThinVec < Attribute > ) -> PResult < ' a , P < Expr > > {
3781- if self . check_keyword ( keywords:: Let ) {
3782- return self . parse_if_let_expr ( attrs) ;
3783- }
37843774 let lo = self . prev_span ;
37853775 let cond = self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL , None ) ?;
37863776
@@ -3812,22 +3802,18 @@ impl<'a> Parser<'a> {
38123802 Ok ( self . mk_expr ( lo. to ( hi) , ExprKind :: If ( cond, thn, els) , attrs) )
38133803 }
38143804
3815- /// Parses an `if let` expression (`if` token already eaten) .
3816- fn parse_if_let_expr ( & mut self , attrs : ThinVec < Attribute > )
3817- -> PResult < ' a , P < Expr > > {
3805+ /// Parses a ` let $pats = $expr` pseudo-expression .
3806+ /// The `let` token has already been eaten.
3807+ fn parse_let_expr ( & mut self , attrs : ThinVec < Attribute > ) -> PResult < ' a , P < Expr > > {
38183808 let lo = self . prev_span ;
3819- self . expect_keyword ( keywords:: Let ) ?;
38203809 let pats = self . parse_pats ( ) ?;
38213810 self . expect ( & token:: Eq ) ?;
3822- let expr = self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL , None ) ?;
3823- let thn = self . parse_block ( ) ?;
3824- let ( hi, els) = if self . eat_keyword ( keywords:: Else ) {
3825- let expr = self . parse_else_expr ( ) ?;
3826- ( expr. span , Some ( expr) )
3827- } else {
3828- ( thn. span , None )
3829- } ;
3830- Ok ( self . mk_expr ( lo. to ( hi) , ExprKind :: IfLet ( pats, expr, thn, els) , attrs) )
3811+
3812+ let expr = self . with_res (
3813+ Restrictions :: NO_STRUCT_LITERAL ,
3814+ |this| this. parse_assoc_expr_with ( 1 + AssocOp :: LAnd . precedence ( ) , None . into ( ) )
3815+ ) ?;
3816+ Ok ( self . mk_expr ( lo. to ( expr. span ) , ExprKind :: Let ( pats, expr) , attrs) )
38313817 }
38323818
38333819 /// Parses `move |args| expr`.
@@ -3930,30 +3916,13 @@ impl<'a> Parser<'a> {
39303916 fn parse_while_expr ( & mut self , opt_label : Option < Label > ,
39313917 span_lo : Span ,
39323918 mut attrs : ThinVec < Attribute > ) -> PResult < ' a , P < Expr > > {
3933- if self . token . is_keyword ( keywords:: Let ) {
3934- return self . parse_while_let_expr ( opt_label, span_lo, attrs) ;
3935- }
39363919 let cond = self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL , None ) ?;
39373920 let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) ?;
39383921 attrs. extend ( iattrs) ;
39393922 let span = span_lo. to ( body. span ) ;
39403923 return Ok ( self . mk_expr ( span, ExprKind :: While ( cond, body, opt_label) , attrs) ) ;
39413924 }
39423925
3943- /// Parses a `while let` expression (`while` token already eaten).
3944- fn parse_while_let_expr ( & mut self , opt_label : Option < Label > ,
3945- span_lo : Span ,
3946- mut attrs : ThinVec < Attribute > ) -> PResult < ' a , P < Expr > > {
3947- self . expect_keyword ( keywords:: Let ) ?;
3948- let pats = self . parse_pats ( ) ?;
3949- self . expect ( & token:: Eq ) ?;
3950- let expr = self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL , None ) ?;
3951- let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) ?;
3952- attrs. extend ( iattrs) ;
3953- let span = span_lo. to ( body. span ) ;
3954- return Ok ( self . mk_expr ( span, ExprKind :: WhileLet ( pats, expr, body, opt_label) , attrs) ) ;
3955- }
3956-
39573926 // parse `loop {...}`, `loop` token already eaten
39583927 fn parse_loop_expr ( & mut self , opt_label : Option < Label > ,
39593928 span_lo : Span ,
0 commit comments