@@ -288,31 +288,51 @@ static Expr *makeBinOp(ASTContext &Ctx, Expr *Op, Expr *LHS, Expr *RHS,
288288
289289 if (auto *ternary = dyn_cast<TernaryExpr>(Op)) {
290290 // Resolve the ternary expression.
291- ASSERT (!ternary->isFolded () && " already folded if expr in sequence?!" );
291+ if (!Ctx.CompletionCallback ) {
292+ // In code completion we might call preCheckTarget twice - once for
293+ // the first pass and once for the second pass. This is fine since
294+ // preCheckTarget is idempotent.
295+ assert (!ternary->isFolded () && " already folded if expr in sequence?!" );
296+ }
292297 ternary->setCondExpr (LHS);
293298 ternary->setElseExpr (RHS);
294299 return ternary;
295300 }
296301
297302 if (auto *assign = dyn_cast<AssignExpr>(Op)) {
298303 // Resolve the assignment expression.
299- ASSERT (!assign->isFolded () && " already folded assign expr in sequence?!" );
304+ if (!Ctx.CompletionCallback ) {
305+ // In code completion we might call preCheckTarget twice - once for
306+ // the first pass and once for the second pass. This is fine since
307+ // preCheckTarget is idempotent.
308+ assert (!assign->isFolded () && " already folded assign expr in sequence?!" );
309+ }
300310 assign->setDest (LHS);
301311 assign->setSrc (RHS);
302312 return assign;
303313 }
304314
305315 if (auto *as = dyn_cast<ExplicitCastExpr>(Op)) {
306316 // Resolve the 'as' or 'is' expression.
307- ASSERT (!as->isFolded () && " already folded 'as' expr in sequence?!" );
317+ if (!Ctx.CompletionCallback ) {
318+ // In code completion we might call preCheckTarget twice - once for
319+ // the first pass and once for the second pass. This is fine since
320+ // preCheckTarget is idempotent.
321+ assert (!as->isFolded () && " already folded 'as' expr in sequence?!" );
322+ }
308323 assert (RHS == as && " 'as' with non-type RHS?!" );
309324 as->setSubExpr (LHS);
310325 return as;
311326 }
312327
313328 if (auto *arrow = dyn_cast<ArrowExpr>(Op)) {
314329 // Resolve the '->' expression.
315- ASSERT (!arrow->isFolded () && " already folded '->' expr in sequence?!" );
330+ if (!Ctx.CompletionCallback ) {
331+ // In code completion we might call preCheckTarget twice - once for
332+ // the first pass and once for the second pass. This is fine since
333+ // preCheckTarget is idempotent.
334+ assert (!arrow->isFolded () && " already folded '->' expr in sequence?!" );
335+ }
316336 arrow->setArgsExpr (LHS);
317337 arrow->setResultExpr (RHS);
318338 return arrow;
@@ -617,10 +637,9 @@ Expr *TypeChecker::foldSequence(SequenceExpr *expr, DeclContext *dc) {
617637 // the folded expression if we've already folded the sequence.
618638 // FIXME: We ought to fix completion to not pre-check multiple times, strictly
619639 // speaking it isn't idempotent (e.g for things like `markDirectCallee`).
620- if (auto *folded = expr->getFoldedExpr ()) {
621- ASSERT (dc->getASTContext ().CompletionCallback &&
622- " Attempting to fold sequence twice?" );
623- return folded;
640+ if (dc->getASTContext ().CompletionCallback ) {
641+ if (auto *folded = expr->getFoldedExpr ())
642+ return folded;
624643 }
625644 // First resolve any unresolved decl references in operator positions.
626645 for (auto i : indices (expr->getElements ())) {
0 commit comments