Skip to content

Commit adc9cc9

Browse files
committed
[CodeComplete] Prefer function call if both reference and call are possible
The real-world use case here is the `Task` initializer in the added test case. In general, we should only prefer to insert an unapplied function reference if it has a better type relation than calling the function because, in most cases, you want to call functions and not get unapplied references to them. rdar://90456105
1 parent 9b10ab3 commit adc9cc9

File tree

2 files changed

+34
-3
lines changed

2 files changed

+34
-3
lines changed

lib/IDE/CompletionLookup.cpp

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1972,10 +1972,11 @@ bool CompletionLookup::addCompoundFunctionNameIfDesiable(
19721972
if (!useFunctionReference && funcTy) {
19731973
// We know that the CodeCompletionResultType is AST-based so we can pass
19741974
// nullptr for USRTypeContext.
1975-
auto maxRel = CodeCompletionResultType(funcTy).calculateTypeRelation(
1975+
auto maxFuncTyRel = CodeCompletionResultType(funcTy).calculateTypeRelation(
19761976
&expectedTypeContext, CurrDeclContext, /*USRTypeContext=*/nullptr);
1977-
useFunctionReference =
1978-
maxRel >= CodeCompletionResultTypeRelation::Convertible;
1977+
auto maxResultTyRel = CodeCompletionResultType(funcTy->getResult()).calculateTypeRelation(
1978+
&expectedTypeContext, CurrDeclContext, /*USRTypeContext=*/nullptr);
1979+
useFunctionReference = maxFuncTyRel > maxResultTyRel;
19791980
}
19801981
if (!useFunctionReference)
19811982
return false;
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
// RUN: %batch-code-completion
2+
3+
struct Route {
4+
func makeDetailView() -> Int {
5+
return 52
6+
}
7+
}
8+
9+
@resultBuilder struct ViewBuilder {
10+
static func buildBlock(_ x: Int) -> Int { return x }
11+
}
12+
13+
func foo(@ViewBuilder destination: () -> Int) {}
14+
func foo(destination: Int) {}
15+
16+
func test(route: Route?) {
17+
route.map { route in
18+
foo(destination: route.#^COMPLETE^#)
19+
}
20+
}
21+
22+
23+
// COMPLETE-DAG: Keyword[self]/CurrNominal: self[#Route#];
24+
// COMPLETE-DAG: Decl[InstanceMethod]/CurrNominal/TypeRelation[Convertible]: makeDetailView()[#Int#];
25+
26+
func testTask(route: Route) {
27+
Task {
28+
route.#^IN_TASK?check=COMPLETE^#
29+
}
30+
}

0 commit comments

Comments
 (0)