Skip to content

Commit 1a7d987

Browse files
authored
Merge pull request #38474 from ahoppen/pr/dont-precheck-twice
[CodeCompletion] Allow preChecking an expression twice in code completion
2 parents 9789130 + 202905f commit 1a7d987

File tree

2 files changed

+27
-4
lines changed

2 files changed

+27
-4
lines changed

lib/Sema/TypeCheckExpr.cpp

Lines changed: 24 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -355,31 +355,51 @@ static Expr *makeBinOp(ASTContext &Ctx, Expr *Op, Expr *LHS, Expr *RHS,
355355

356356
if (auto *ifExpr = dyn_cast<IfExpr>(Op)) {
357357
// Resolve the ternary expression.
358-
assert(!ifExpr->isFolded() && "already folded if expr in sequence?!");
358+
if (!Ctx.CompletionCallback) {
359+
// In code completion we might call preCheckExpression twice - once for
360+
// the first pass and once for the second pass. This is fine since
361+
// preCheckExpression idempotent.
362+
assert(!ifExpr->isFolded() && "already folded if expr in sequence?!");
363+
}
359364
ifExpr->setCondExpr(LHS);
360365
ifExpr->setElseExpr(RHS);
361366
return ifExpr;
362367
}
363368

364369
if (auto *assign = dyn_cast<AssignExpr>(Op)) {
365370
// Resolve the assignment expression.
366-
assert(!assign->isFolded() && "already folded assign expr in sequence?!");
371+
if (!Ctx.CompletionCallback) {
372+
// In code completion we might call preCheckExpression twice - once for
373+
// the first pass and once for the second pass. This is fine since
374+
// preCheckExpression idempotent.
375+
assert(!assign->isFolded() && "already folded assign expr in sequence?!");
376+
}
367377
assign->setDest(LHS);
368378
assign->setSrc(RHS);
369379
return assign;
370380
}
371381

372382
if (auto *as = dyn_cast<ExplicitCastExpr>(Op)) {
373383
// Resolve the 'as' or 'is' expression.
374-
assert(!as->isFolded() && "already folded 'as' expr in sequence?!");
384+
if (!Ctx.CompletionCallback) {
385+
// In code completion we might call preCheckExpression twice - once for
386+
// the first pass and once for the second pass. This is fine since
387+
// preCheckExpression idempotent.
388+
assert(!as->isFolded() && "already folded 'as' expr in sequence?!");
389+
}
375390
assert(RHS == as && "'as' with non-type RHS?!");
376391
as->setSubExpr(LHS);
377392
return as;
378393
}
379394

380395
if (auto *arrow = dyn_cast<ArrowExpr>(Op)) {
381396
// Resolve the '->' expression.
382-
assert(!arrow->isFolded() && "already folded '->' expr in sequence?!");
397+
if (!Ctx.CompletionCallback) {
398+
// In code completion we might call preCheckExpression twice - once for
399+
// the first pass and once for the second pass. This is fine since
400+
// preCheckExpression idempotent.
401+
assert(!arrow->isFolded() && "already folded '->' expr in sequence?!");
402+
}
383403
arrow->setArgsExpr(LHS);
384404
arrow->setResultExpr(RHS);
385405
return arrow;
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
// RUN: %swift-ide-test --code-completion --source-filename %s --code-completion-token=COMPLETE
2+
3+
Foo.#^COMPLETE^#bar ?? baz(_) = baba

0 commit comments

Comments
 (0)