@@ -288,51 +288,31 @@ 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- 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- }
291+ ASSERT (!ternary->isFolded () && " already folded if expr in sequence?!" );
297292 ternary->setCondExpr (LHS);
298293 ternary->setElseExpr (RHS);
299294 return ternary;
300295 }
301296
302297 if (auto *assign = dyn_cast<AssignExpr>(Op)) {
303298 // Resolve the assignment expression.
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- }
299+ ASSERT (!assign->isFolded () && " already folded assign expr in sequence?!" );
310300 assign->setDest (LHS);
311301 assign->setSrc (RHS);
312302 return assign;
313303 }
314304
315305 if (auto *as = dyn_cast<ExplicitCastExpr>(Op)) {
316306 // Resolve the 'as' or 'is' expression.
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- }
307+ ASSERT (!as->isFolded () && " already folded 'as' expr in sequence?!" );
323308 assert (RHS == as && " 'as' with non-type RHS?!" );
324309 as->setSubExpr (LHS);
325310 return as;
326311 }
327312
328313 if (auto *arrow = dyn_cast<ArrowExpr>(Op)) {
329314 // Resolve the '->' expression.
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- }
315+ ASSERT (!arrow->isFolded () && " already folded '->' expr in sequence?!" );
336316 arrow->setArgsExpr (LHS);
337317 arrow->setResultExpr (RHS);
338318 return arrow;
@@ -633,6 +613,15 @@ swift::DefaultTypeRequest::evaluate(Evaluator &evaluator,
633613}
634614
635615Expr *TypeChecker::foldSequence (SequenceExpr *expr, DeclContext *dc) {
616+ // We may end up running pre-checking multiple times for completion, just use
617+ // the folded expression if we've already folded the sequence.
618+ // FIXME: We ought to fix completion to not pre-check multiple times, strictly
619+ // 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;
624+ }
636625 // First resolve any unresolved decl references in operator positions.
637626 for (auto i : indices (expr->getElements ())) {
638627 if (i % 2 == 0 )
0 commit comments