Skip to content

Commit 52e3109

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 8c970ab commit 52e3109

File tree

2 files changed

+24
-2
lines changed

2 files changed

+24
-2
lines changed

lib/IDE/CodeCompletion.cpp

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

32703270
void tryPostfixOperator(Expr *expr, PostfixOperatorDecl *op) {
3271-
if (!expr->getType())
3271+
auto Ty = expr->getType();
3272+
if (!Ty)
32723273
return;
3274+
3275+
SWIFT_DEFER {
3276+
// Restore type.
3277+
// FIXME: This is workaround for getTypeOfExpressionWithoutApplying()
3278+
// modifies type of 'expr'.
3279+
expr->setType(Ty);
3280+
};
3281+
32733282
// We allocate these expressions on the stack because we know they can't
32743283
// escape and there isn't a better way to allocate scratch Expr nodes.
32753284
UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::PostfixOperator,
@@ -3344,6 +3353,9 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
33443353
LHS->getType()->is<AnyFunctionType>()))
33453354
return;
33463355

3356+
// Preserve LHS type for restoring it.
3357+
Type LHSTy = LHS->getType();
3358+
33473359
// We allocate these expressions on the stack because we know they can't
33483360
// escape and there isn't a better way to allocate scratch Expr nodes.
33493361
UnresolvedDeclRefExpr UDRE(op->getName(), DeclRefKind::BinaryOperator,
@@ -3356,6 +3368,7 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
33563368
// Reset sequence.
33573369
SE->setElement(SE->getNumElements() - 1, nullptr);
33583370
SE->setElement(SE->getNumElements() - 2, nullptr);
3371+
LHS->setType(LHSTy);
33593372
prepareForRetypechecking(SE);
33603373

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

test/IDE/complete_crashes.swift

Lines changed: 10 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 | %FileCheck %s -check-prefix=RDAR_41159258
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,13 @@ 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-DAG: Keyword[self]/CurrNominal: .self[#(_) -> ()#]; name=self
298+
// RDAR_28188259: End completions

0 commit comments

Comments
 (0)