@@ -3458,11 +3458,17 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3458
3458
SE->setElement (SE->getNumElements () - 2 , nullptr );
3459
3459
prepareForRetypechecking (SE);
3460
3460
3461
- // Reset any references to operators in types, so they are properly
3462
- // handled as operators by sequence folding.
3463
- //
3464
- // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
3465
3461
for (auto &element : sequence.drop_back (2 )) {
3462
+ // Unfold AssignExpr for re-typechecking sequence.
3463
+ if (auto *AE = dyn_cast_or_null<AssignExpr>(element)) {
3464
+ AE->setSrc (nullptr );
3465
+ AE->setDest (nullptr );
3466
+ }
3467
+
3468
+ // Reset any references to operators in types, so they are properly
3469
+ // handled as operators by sequence folding.
3470
+ //
3471
+ // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
3466
3472
if (auto operatorRef = element->getMemberOperatorRef ()) {
3467
3473
operatorRef->setType (nullptr );
3468
3474
element = operatorRef;
@@ -3496,20 +3502,20 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3496
3502
}
3497
3503
}
3498
3504
3499
- void flattenBinaryExpr (BinaryExpr *expr, SmallVectorImpl<Expr *> &sequence) {
3500
- auto LHS = expr-> getArg ()-> getElement ( 0 );
3501
- if ( auto binexpr = dyn_cast<BinaryExpr>(LHS))
3502
- flattenBinaryExpr (binexpr, sequence);
3503
- else
3504
- sequence. push_back (LHS);
3505
-
3506
- sequence.push_back (expr-> getFn () );
3507
-
3508
- auto RHS = expr-> getArg ()-> getElement ( 1 );
3509
- if ( auto binexpr = dyn_cast<BinaryExpr>(RHS))
3510
- flattenBinaryExpr (binexpr, sequence);
3511
- else
3512
- sequence. push_back (RHS);
3505
+ void flattenBinaryExpr (Expr *expr, SmallVectorImpl<Expr *> &sequence) {
3506
+ if ( auto binExpr = dyn_cast<BinaryExpr>(expr)) {
3507
+ flattenBinaryExpr (binExpr-> getArg ()-> getElement ( 0 ), sequence);
3508
+ sequence. push_back (binExpr-> getFn () );
3509
+ flattenBinaryExpr (binExpr-> getArg ()-> getElement ( 1 ), sequence);
3510
+ } else if ( auto assignExpr = dyn_cast<AssignExpr>(expr)) {
3511
+ flattenBinaryExpr (assignExpr-> getDest (), sequence);
3512
+ sequence.push_back (assignExpr );
3513
+ flattenBinaryExpr (assignExpr-> getSrc (), sequence);
3514
+ assignExpr-> setDest ( nullptr );
3515
+ assignExpr-> setSrc ( nullptr );
3516
+ } else {
3517
+ sequence. push_back (expr);
3518
+ }
3513
3519
}
3514
3520
3515
3521
void typeCheckLeadingSequence (SmallVectorImpl<Expr *> &sequence) {
@@ -3519,10 +3525,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3519
3525
// Take advantage of the fact the type-checker leaves the types on the AST.
3520
3526
if (!typeCheckExpression (const_cast <DeclContext *>(CurrDeclContext),
3521
3527
expr)) {
3522
- if (auto binexpr = dyn_cast<BinaryExpr >(expr)) {
3528
+ if (isa<BinaryExpr>(expr) || isa<AssignExpr >(expr)) {
3523
3529
// Rebuild the sequence from the type-checked version.
3524
3530
sequence.clear ();
3525
- flattenBinaryExpr (binexpr , sequence);
3531
+ flattenBinaryExpr (expr , sequence);
3526
3532
return ;
3527
3533
}
3528
3534
}
@@ -3548,6 +3554,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3548
3554
if (sequence.size () > 1 )
3549
3555
typeCheckLeadingSequence (sequence);
3550
3556
3557
+ // Retrieve typechecked LHS.
3558
+ LHS = sequence.back ();
3559
+
3551
3560
// Create a single sequence expression, which we will modify for each
3552
3561
// operator, filling in the operator and dummy right-hand side.
3553
3562
sequence.push_back (nullptr ); // operator
0 commit comments