1
+ // ignore-tidy-filelength
1
2
use super :: diagnostics:: SnapshotParser ;
2
3
use super :: pat:: { CommaRecoveryMode , Expected , RecoverColon , RecoverComma } ;
3
4
use super :: ty:: { AllowPlus , RecoverQPath , RecoverReturnSign } ;
@@ -2477,7 +2478,7 @@ impl<'a> Parser<'a> {
2477
2478
let mut cond =
2478
2479
self . parse_expr_res ( Restrictions :: NO_STRUCT_LITERAL | Restrictions :: ALLOW_LET , None ) ?;
2479
2480
2480
- CondChecker { parser : self , forbid_let_reason : None } . visit_expr ( & mut cond) ;
2481
+ CondChecker :: new ( self ) . visit_expr ( & mut cond) ;
2481
2482
2482
2483
if let ExprKind :: Let ( _, _, _, None ) = cond. kind {
2483
2484
// Remove the last feature gating of a `let` expression since it's stable.
@@ -2493,6 +2494,8 @@ impl<'a> Parser<'a> {
2493
2494
let err = errors:: ExpectedExpressionFoundLet {
2494
2495
span : self . token . span ,
2495
2496
reason : ForbiddenLetReason :: OtherForbidden ,
2497
+ missing_let : None ,
2498
+ comparison : None ,
2496
2499
} ;
2497
2500
if self . prev_token . kind == token:: BinOp ( token:: Or ) {
2498
2501
// This was part of a closure, the that part of the parser recover.
@@ -2876,7 +2879,7 @@ impl<'a> Parser<'a> {
2876
2879
let if_span = this. prev_token . span ;
2877
2880
let mut cond = this. parse_match_guard_condition ( ) ?;
2878
2881
2879
- CondChecker { parser : this , forbid_let_reason : None } . visit_expr ( & mut cond) ;
2882
+ CondChecker :: new ( this ) . visit_expr ( & mut cond) ;
2880
2883
2881
2884
let ( has_let_expr, does_not_have_bin_op) = check_let_expr ( & cond) ;
2882
2885
if has_let_expr {
@@ -3552,6 +3555,14 @@ pub(crate) enum ForbiddenLetReason {
3552
3555
struct CondChecker < ' a > {
3553
3556
parser : & ' a Parser < ' a > ,
3554
3557
forbid_let_reason : Option < ForbiddenLetReason > ,
3558
+ missing_let : Option < errors:: MaybeMissingLet > ,
3559
+ comparison : Option < errors:: MaybeComparison > ,
3560
+ }
3561
+
3562
+ impl < ' a > CondChecker < ' a > {
3563
+ fn new ( parser : & ' a Parser < ' a > ) -> Self {
3564
+ CondChecker { parser, forbid_let_reason : None , missing_let : None , comparison : None }
3565
+ }
3555
3566
}
3556
3567
3557
3568
impl MutVisitor for CondChecker < ' _ > {
@@ -3562,11 +3573,13 @@ impl MutVisitor for CondChecker<'_> {
3562
3573
match e. kind {
3563
3574
ExprKind :: Let ( _, _, _, ref mut is_recovered @ None ) => {
3564
3575
if let Some ( reason) = self . forbid_let_reason {
3565
- * is_recovered = Some (
3566
- self . parser
3567
- . sess
3568
- . emit_err ( errors:: ExpectedExpressionFoundLet { span, reason } ) ,
3569
- ) ;
3576
+ * is_recovered =
3577
+ Some ( self . parser . sess . emit_err ( errors:: ExpectedExpressionFoundLet {
3578
+ span,
3579
+ reason,
3580
+ missing_let : self . missing_let ,
3581
+ comparison : self . comparison ,
3582
+ } ) ) ;
3570
3583
} else {
3571
3584
self . parser . sess . gated_spans . gate ( sym:: let_chains, span) ;
3572
3585
}
@@ -3590,9 +3603,28 @@ impl MutVisitor for CondChecker<'_> {
3590
3603
noop_visit_expr ( e, self ) ;
3591
3604
self . forbid_let_reason = forbid_let_reason;
3592
3605
}
3606
+ ExprKind :: Assign ( ref lhs, _, span) => {
3607
+ let forbid_let_reason = self . forbid_let_reason ;
3608
+ self . forbid_let_reason = Some ( OtherForbidden ) ;
3609
+ let missing_let = self . missing_let ;
3610
+ if let ExprKind :: Binary ( _, _, rhs) = & lhs. kind
3611
+ && let ExprKind :: Path ( _, _)
3612
+ | ExprKind :: Struct ( _)
3613
+ | ExprKind :: Call ( _, _)
3614
+ | ExprKind :: Array ( _) = rhs. kind
3615
+ {
3616
+ self . missing_let =
3617
+ Some ( errors:: MaybeMissingLet { span : rhs. span . shrink_to_lo ( ) } ) ;
3618
+ }
3619
+ let comparison = self . comparison ;
3620
+ self . comparison = Some ( errors:: MaybeComparison { span : span. shrink_to_hi ( ) } ) ;
3621
+ noop_visit_expr ( e, self ) ;
3622
+ self . forbid_let_reason = forbid_let_reason;
3623
+ self . missing_let = missing_let;
3624
+ self . comparison = comparison;
3625
+ }
3593
3626
ExprKind :: Unary ( _, _)
3594
3627
| ExprKind :: Await ( _, _)
3595
- | ExprKind :: Assign ( _, _, _)
3596
3628
| ExprKind :: AssignOp ( _, _, _)
3597
3629
| ExprKind :: Range ( _, _, _)
3598
3630
| ExprKind :: Try ( _)
0 commit comments