Skip to content

Commit 3402127

Browse files
committed
[CodeComplete] Restore original type in getOperatorCompletions
In getOperatorCompletions(), for each every known operators, temporary expressions are created and typechecked. In this process, typechecker may set the type of the parsed expression. That may cause non-accurate completion results or crash at worst. rdar://problem/28188259
1 parent f577578 commit 3402127

File tree

2 files changed

+23
-2
lines changed

2 files changed

+23
-2
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 14 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3368,8 +3368,17 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
33683368
}
33693369

33703370
void tryPostfixOperator(Expr *expr, PostfixOperatorDecl *op) {
3371-
if (!expr->getType())
3371+
auto Ty = expr->getType();
3372+
if (!Ty)
33723373
return;
3374+
3375+
SWIFT_DEFER {
3376+
// Restore type.
3377+
// FIXME: This is workaround for getTypeOfExpressionWithoutApplying()
3378+
// modifies type of 'expr'.
3379+
expr->setType(Ty);
3380+
};
3381+
33733382
// We allocate these expressions on the stack because we know they can't
33743383
// escape and there isn't a better way to allocate scratch Expr nodes.
33753384
UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::PostfixOperator,
@@ -3444,6 +3453,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
34443453
LHS->getType()->is<AnyFunctionType>()))
34453454
return;
34463455

3456+
// Preserve LHS type for restoring it.
3457+
Type LHSTy = LHS->getType();
3458+
34473459
// We allocate these expressions on the stack because we know they can't
34483460
// escape and there isn't a better way to allocate scratch Expr nodes.
34493461
UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::BinaryOperator,
@@ -3456,6 +3468,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
34563468
// Reset sequence.
34573469
SE->setElement(SE->getNumElements() - 1, nullptr);
34583470
SE->setElement(SE->getNumElements() - 2, nullptr);
3471+
LHS->setType(LHSTy);
34593472
prepareForRetypechecking(SE);
34603473

34613474
for (auto &element : sequence.drop_back(2)) {

test/IDE/complete_crashes.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -246,7 +246,6 @@ func foo_38272904(a: A_38272904) {
246246
}
247247
// RDAR_38272904: Begin completions
248248

249-
250249
// rdar://problem/41159258
251250
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41159258_1
252251
// RUN: %target-swift-ide-test -code-completion -source-filename=%s -code-completion-token=RDAR41159258_2 | %FileCheck %s -check-prefix=RDAR_41159258
@@ -287,3 +286,12 @@ public final class IntStore {
287286
}
288287
}
289288
// RDAR_41232519: Begin completions
289+
290+
// rdar://problem/28188259
291+
// RUN: %target-swift-ide-test -code-completion -code-completion-token=RDAR_28188259 -source-filename=%s | %FileCheck %s -check-prefix=RDAR_28188259
292+
func test_28188259(x: ((Int) -> Void) -> Void) {
293+
x({_ in }#^RDAR_28188259^#)
294+
}
295+
// RDAR_28188259: Begin completions
296+
// RDAR_28188259-DAG: Pattern/CurrModule: ({#_#})[#Void#]; name=(_)
297+
// RDAR_28188259: End completions

0 commit comments

Comments
 (0)