@@ -2621,13 +2621,8 @@ impl<'a> Parser<'a> {
2621
2621
} else {
2622
2622
ex = ExprKind :: Yield ( None ) ;
2623
2623
}
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) ;
2631
2626
} else if self . span . rust_2018 ( ) && self . eat_keyword ( keywords:: Await ) {
2632
2627
// FIXME: remove this branch when `await!` is no longer supported
2633
2628
// https://github.com/rust-lang/rust/issues/60610
@@ -2886,15 +2881,13 @@ impl<'a> Parser<'a> {
2886
2881
attrs. extend :: < Vec < _ > > ( expr. attrs . into ( ) ) ;
2887
2882
expr. attrs = attrs;
2888
2883
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") ;
2898
2891
}
2899
2892
_ => { }
2900
2893
}
@@ -3778,9 +3771,6 @@ impl<'a> Parser<'a> {
3778
3771
3779
3772
/// Parses an `if` or `if let` expression (`if` token already eaten).
3780
3773
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
- }
3784
3774
let lo = self . prev_span ;
3785
3775
let cond = self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL , None ) ?;
3786
3776
@@ -3812,22 +3802,18 @@ impl<'a> Parser<'a> {
3812
3802
Ok ( self . mk_expr ( lo. to ( hi) , ExprKind :: If ( cond, thn, els) , attrs) )
3813
3803
}
3814
3804
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 > > {
3818
3808
let lo = self . prev_span ;
3819
- self . expect_keyword ( keywords:: Let ) ?;
3820
3809
let pats = self . parse_pats ( ) ?;
3821
3810
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) )
3831
3817
}
3832
3818
3833
3819
/// Parses `move |args| expr`.
@@ -3930,30 +3916,13 @@ impl<'a> Parser<'a> {
3930
3916
fn parse_while_expr ( & mut self , opt_label : Option < Label > ,
3931
3917
span_lo : Span ,
3932
3918
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
- }
3936
3919
let cond = self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL , None ) ?;
3937
3920
let ( iattrs, body) = self . parse_inner_attrs_and_block ( ) ?;
3938
3921
attrs. extend ( iattrs) ;
3939
3922
let span = span_lo. to ( body. span ) ;
3940
3923
return Ok ( self . mk_expr ( span, ExprKind :: While ( cond, body, opt_label) , attrs) ) ;
3941
3924
}
3942
3925
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
-
3957
3926
// parse `loop {...}`, `loop` token already eaten
3958
3927
fn parse_loop_expr ( & mut self , opt_label : Option < Label > ,
3959
3928
span_lo : Span ,
0 commit comments