Skip to content

Commit 114d836

Browse files
authored
Merge pull request #5183 from benlangmuir/cc-inst-curry-ref
[code-completion] Fix type-relation check on implicitly curried instance methods
2 parents 34d81d4 + a6934d1 commit 114d836

File tree

2 files changed

+61
-30
lines changed

2 files changed

+61
-30
lines changed

lib/IDE/CodeCompletion.cpp

Lines changed: 30 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -927,6 +927,7 @@ static CodeCompletionResult::ExpectedTypeRelation calculateTypeRelation(
927927

928928
static CodeCompletionResult::ExpectedTypeRelation
929929
calculateTypeRelationForDecl(const Decl *D, Type ExpectedType,
930+
bool IsImplicitlyCurriedInstanceMethod,
930931
bool UseFuncResultType = true) {
931932
auto VD = dyn_cast<ValueDecl>(D);
932933
auto DC = D->getDeclContext();
@@ -935,7 +936,8 @@ calculateTypeRelationForDecl(const Decl *D, Type ExpectedType,
935936

936937
if (auto FD = dyn_cast<AbstractFunctionDecl>(VD)) {
937938
auto funcType = FD->getType()->getAs<AnyFunctionType>();
938-
if (DC->isTypeContext() && funcType && funcType->is<AnyFunctionType>())
939+
if (DC->isTypeContext() && funcType && funcType->is<AnyFunctionType>() &&
940+
!IsImplicitlyCurriedInstanceMethod)
939941
funcType = funcType->getResult()->getAs<AnyFunctionType>();
940942
if (funcType) {
941943
auto relation = calculateTypeRelation(funcType, ExpectedType, DC);
@@ -953,12 +955,15 @@ calculateTypeRelationForDecl(const Decl *D, Type ExpectedType,
953955
return calculateTypeRelation(VD->getType(), ExpectedType, DC);
954956
}
955957

956-
static CodeCompletionResult::ExpectedTypeRelation calculateMaxTypeRelationForDecl (
957-
const Decl *D,
958-
ArrayRef<Type> ExpectedTypes) {
958+
static CodeCompletionResult::ExpectedTypeRelation
959+
calculateMaxTypeRelationForDecl(
960+
const Decl *D,
961+
ArrayRef<Type> ExpectedTypes,
962+
bool IsImplicitlyCurriedInstanceMethod = false) {
959963
auto Result = CodeCompletionResult::ExpectedTypeRelation::Unrelated;
960964
for (auto Type : ExpectedTypes) {
961-
Result = std::max(Result, calculateTypeRelationForDecl(D, Type));
965+
Result = std::max(Result, calculateTypeRelationForDecl(
966+
D, Type, IsImplicitlyCurriedInstanceMethod));
962967
}
963968
return Result;
964969
}
@@ -1645,9 +1650,11 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
16451650
bool shouldUseFunctionReference(AbstractFunctionDecl *D) {
16461651
if (PreferFunctionReferencesToCalls)
16471652
return true;
1653+
bool isImplicitlyCurriedIM = isImplicitlyCurriedInstanceMethod(D);
16481654
for (auto expectedType : ExpectedTypes) {
16491655
if (expectedType && expectedType->is<AnyFunctionType>() &&
1650-
calculateTypeRelationForDecl(D, expectedType, false) >=
1656+
calculateTypeRelationForDecl(D, expectedType, isImplicitlyCurriedIM,
1657+
/*UseFuncResult=*/false) >=
16511658
CodeCompletionResult::ExpectedTypeRelation::Convertible) {
16521659
return true;
16531660
}
@@ -2338,39 +2345,34 @@ class CompletionLookup final : public swift::VisibleDeclConsumer {
23382345
addPattern(/*includeDefaultArgs*/ false);
23392346
addPattern();
23402347
}
2341-
2342-
void addMethodCall(const FuncDecl *FD, DeclVisibilityKind Reason) {
2343-
if (FD->getName().empty())
2344-
return;
2345-
foundFunction(FD);
2346-
bool IsImplicitlyCurriedInstanceMethod;
2348+
bool isImplicitlyCurriedInstanceMethod(const AbstractFunctionDecl *FD) {
23472349
switch (Kind) {
23482350
case LookupKind::ValueExpr:
2349-
IsImplicitlyCurriedInstanceMethod = ExprType->is<AnyMetatypeType>() &&
2350-
!FD->isStatic();
2351-
break;
2351+
return ExprType->is<AnyMetatypeType>() && !FD->isStatic();
23522352
case LookupKind::ValueInDeclContext:
2353-
IsImplicitlyCurriedInstanceMethod =
2354-
InsideStaticMethod &&
2353+
if (InsideStaticMethod &&
23552354
FD->getDeclContext() == CurrentMethod->getDeclContext() &&
2356-
!FD->isStatic();
2357-
if (!IsImplicitlyCurriedInstanceMethod) {
2358-
if (auto Init = dyn_cast<Initializer>(CurrDeclContext)) {
2359-
IsImplicitlyCurriedInstanceMethod =
2360-
FD->getDeclContext() == Init->getParent() &&
2361-
!FD->isStatic();
2362-
}
2363-
}
2364-
break;
2355+
!FD->isStatic())
2356+
return true;
2357+
if (auto Init = dyn_cast<Initializer>(CurrDeclContext))
2358+
return FD->getDeclContext() == Init->getParent() && !FD->isStatic();
2359+
return false;
23652360
case LookupKind::EnumElement:
23662361
case LookupKind::Type:
23672362
case LookupKind::TypeInDeclContext:
23682363
llvm_unreachable("cannot have a method call while doing a "
23692364
"type completion");
23702365
case LookupKind::ImportFromModule:
2371-
IsImplicitlyCurriedInstanceMethod = false;
2372-
break;
2366+
return false;
23732367
}
2368+
}
2369+
2370+
void addMethodCall(const FuncDecl *FD, DeclVisibilityKind Reason) {
2371+
if (FD->getName().empty())
2372+
return;
2373+
foundFunction(FD);
2374+
bool IsImplicitlyCurriedInstanceMethod =
2375+
isImplicitlyCurriedInstanceMethod(FD);
23742376

23752377
StringRef Name = FD->getName().get();
23762378
assert(!Name.empty() && "name should not be empty");

test/IDE/complete_func_reference.swift

Lines changed: 31 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,14 @@
55
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_VOID_4 | %FileCheck %s -check-prefix=VOID_VOID
66
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_0 | %FileCheck %s -check-prefix=ANY_INT
77
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_1 | %FileCheck %s -check-prefix=ANY_INT
8-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_2 | %FileCheck %s -check-prefix=ANY_INT
8+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=ANY_INT_2 > %t.results
9+
// RUN:%FileCheck %s -check-prefix=ANY_INT < %t.results
10+
// RUN:%FileCheck %s -check-prefix=ANY_INT_STATIC_CURRY < %t.results
911
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_0 | %FileCheck %s -check-prefix=INT_ANY
1012
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_1 | %FileCheck %s -check-prefix=INT_ANY
11-
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_2 | %FileCheck %s -check-prefix=INT_ANY
13+
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=INT_ANY_2 > %t.results
14+
// RUN: %FileCheck %s -check-prefix=INT_ANY < %t.results
15+
// RUN: %FileCheck %s -check-prefix=INT_ANY_STATIC_CURRY < %t.results
1216
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_0 | %FileCheck %s -check-prefix=VOID_INT_INT
1317
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_1 | %FileCheck %s -check-prefix=VOID_INT_INT
1418
// RUN: %target-swift-ide-test -code-completion -source-filename %s -code-completion-token=VOID_INT_INT_2 | %FileCheck %s -check-prefix=VOID_INT_INT
@@ -119,6 +123,19 @@ do {
119123
// ANY_INT-DAG: Decl{{.*}}: returnsIntToInt()[#(Int) -> Int#];
120124
// ANY_INT: End completions
121125

126+
// ANY_INT_STATIC_CURRY: Begin completions
127+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToInt({#self: S0#})[#(a: Any) -> Int#];
128+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: voidToVoid({#self: S0#})[#() -> Void#];
129+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: intToVoid({#self: S0#})[#(a: Int) -> Void#];
130+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/NotRecommended/TypeRelation[Invalid]: anyToVoid({#self: S0#})[#(a: Any) -> Void#];
131+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: voidToInt({#self: S0#})[#() -> Int#];
132+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: intToInt({#self: S0#})[#(a: Int) -> Int#];
133+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: voidToAny({#self: S0#})[#() -> Any#];
134+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: anyToAny({#self: S0#})[#(a: Any) -> Any#];
135+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: intToAny({#self: S0#})[#(a: Int) -> Any#];
136+
// ANY_INT_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: returnsIntToInt({#self: S0#})[#() -> (Int) -> Int#];
137+
// ANY_INT_STATIC_CURRY: End completions
138+
122139
do {
123140
func take(_: @escaping (Int)->Any) {}
124141
take(#^INT_ANY_0^#)
@@ -137,6 +154,18 @@ do {
137154
// INT_ANY-DAG: Decl{{.*}}: voidToAny()[#Any#];
138155
// INT_ANY: End completions
139156

157+
// INT_ANY_STATIC_CURRY: Begin completions
158+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: intToInt({#self: S0#})[#(a: Int) -> Int#];
159+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: intToVoid({#self: S0#})[#(a: Int) -> Void#];
160+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToAny({#self: S0#})[#(a: Any) -> Any#];
161+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToVoid({#self: S0#})[#(a: Any) -> Void#];
162+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: intToAny({#self: S0#})[#(a: Int) -> Any#];
163+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: anyToInt({#self: S0#})[#(a: Any) -> Int#];
164+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: returnsIntToInt({#self: S0#})[#() -> (Int) -> Int#];
165+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: voidToAny({#self: S0#})[#() -> Any#];
166+
// INT_ANY_STATIC_CURRY-DAG: Decl[InstanceMethod]/CurrNominal: voidToInt({#self: S0#})[#() -> Int#];
167+
// INT_ANY_STATIC_CURRY: End completions
168+
140169
do {
141170
func take(_: @escaping (Int)->Any) {}
142171
take(S0().#^INT_ANY_1^#)

0 commit comments

Comments
 (0)