@@ -3358,11 +3358,17 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3358
3358
SE->setElement (SE->getNumElements () - 2 , nullptr );
3359
3359
prepareForRetypechecking (SE);
3360
3360
3361
- // Reset any references to operators in types, so they are properly
3362
- // handled as operators by sequence folding.
3363
- //
3364
- // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
3365
3361
for (auto &element : sequence.drop_back (2 )) {
3362
+ // Unfold AssignExpr for re-typechecking sequence.
3363
+ if (auto *AE = dyn_cast_or_null<AssignExpr>(element)) {
3364
+ AE->setSrc (nullptr );
3365
+ AE->setDest (nullptr );
3366
+ }
3367
+
3368
+ // Reset any references to operators in types, so they are properly
3369
+ // handled as operators by sequence folding.
3370
+ //
3371
+ // FIXME: Would be better to have some kind of 'OperatorRefExpr'?
3366
3372
if (auto operatorRef = element->getMemberOperatorRef ()) {
3367
3373
operatorRef->setType (nullptr );
3368
3374
element = operatorRef;
@@ -3396,20 +3402,20 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3396
3402
}
3397
3403
}
3398
3404
3399
- void flattenBinaryExpr (BinaryExpr *expr, SmallVectorImpl<Expr *> &sequence) {
3400
- auto LHS = expr-> getArg ()-> getElement ( 0 );
3401
- if ( auto binexpr = dyn_cast<BinaryExpr>(LHS))
3402
- flattenBinaryExpr (binexpr, sequence);
3403
- else
3404
- sequence. push_back (LHS);
3405
-
3406
- sequence.push_back (expr-> getFn () );
3407
-
3408
- auto RHS = expr-> getArg ()-> getElement ( 1 );
3409
- if ( auto binexpr = dyn_cast<BinaryExpr>(RHS))
3410
- flattenBinaryExpr (binexpr, sequence);
3411
- else
3412
- sequence. push_back (RHS);
3405
+ void flattenBinaryExpr (Expr *expr, SmallVectorImpl<Expr *> &sequence) {
3406
+ if ( auto binExpr = dyn_cast<BinaryExpr>(expr)) {
3407
+ flattenBinaryExpr (binExpr-> getArg ()-> getElement ( 0 ), sequence);
3408
+ sequence. push_back (binExpr-> getFn () );
3409
+ flattenBinaryExpr (binExpr-> getArg ()-> getElement ( 1 ), sequence);
3410
+ } else if ( auto assignExpr = dyn_cast<AssignExpr>(expr)) {
3411
+ flattenBinaryExpr (assignExpr-> getDest (), sequence);
3412
+ sequence.push_back (assignExpr );
3413
+ flattenBinaryExpr (assignExpr-> getSrc (), sequence);
3414
+ assignExpr-> setDest ( nullptr );
3415
+ assignExpr-> setSrc ( nullptr );
3416
+ } else {
3417
+ sequence. push_back (expr);
3418
+ }
3413
3419
}
3414
3420
3415
3421
void typeCheckLeadingSequence (SmallVectorImpl<Expr *> &sequence) {
@@ -3419,10 +3425,10 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3419
3425
// Take advantage of the fact the type-checker leaves the types on the AST.
3420
3426
if (!typeCheckExpression (const_cast <DeclContext *>(CurrDeclContext),
3421
3427
expr)) {
3422
- if (auto binexpr = dyn_cast<BinaryExpr >(expr)) {
3428
+ if (isa<BinaryExpr>(expr) || isa<AssignExpr >(expr)) {
3423
3429
// Rebuild the sequence from the type-checked version.
3424
3430
sequence.clear ();
3425
- flattenBinaryExpr (binexpr , sequence);
3431
+ flattenBinaryExpr (expr , sequence);
3426
3432
return ;
3427
3433
}
3428
3434
}
@@ -3448,6 +3454,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
3448
3454
if (sequence.size () > 1 )
3449
3455
typeCheckLeadingSequence (sequence);
3450
3456
3457
+ // Retrieve typechecked LHS.
3458
+ LHS = sequence.back ();
3459
+
3451
3460
// Create a single sequence expression, which we will modify for each
3452
3461
// operator, filling in the operator and dummy right-hand side.
3453
3462
sequence.push_back (nullptr ); // operator
0 commit comments