@@ -288,31 +288,51 @@ static Expr *makeBinOp(ASTContext &Ctx, Expr *Op, Expr *LHS, Expr *RHS,
288
288
289
289
if (auto *ternary = dyn_cast<TernaryExpr>(Op)) {
290
290
// 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
+ }
292
297
ternary->setCondExpr (LHS);
293
298
ternary->setElseExpr (RHS);
294
299
return ternary;
295
300
}
296
301
297
302
if (auto *assign = dyn_cast<AssignExpr>(Op)) {
298
303
// 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
+ }
300
310
assign->setDest (LHS);
301
311
assign->setSrc (RHS);
302
312
return assign;
303
313
}
304
314
305
315
if (auto *as = dyn_cast<ExplicitCastExpr>(Op)) {
306
316
// 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
+ }
308
323
assert (RHS == as && " 'as' with non-type RHS?!" );
309
324
as->setSubExpr (LHS);
310
325
return as;
311
326
}
312
327
313
328
if (auto *arrow = dyn_cast<ArrowExpr>(Op)) {
314
329
// 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
+ }
316
336
arrow->setArgsExpr (LHS);
317
337
arrow->setResultExpr (RHS);
318
338
return arrow;
@@ -617,10 +637,9 @@ Expr *TypeChecker::foldSequence(SequenceExpr *expr, DeclContext *dc) {
617
637
// the folded expression if we've already folded the sequence.
618
638
// FIXME: We ought to fix completion to not pre-check multiple times, strictly
619
639
// 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;
624
643
}
625
644
// First resolve any unresolved decl references in operator positions.
626
645
for (auto i : indices (expr->getElements ())) {
0 commit comments