Skip to content

Commit 8e2f1c5

Browse files
committed
[CSSimplify] Disfavor choices that have injected callAsFunction
Ambiguities like: ``` struct S { init(v: Int) {} init(v: Int, _: () -> Void) {} func callAsFunction(_: () -> Void) {} } S(v: 42) { } ``` Should always be resolved in favor of choice that doesn't require injection of `.callAsFunction`, so let's try to avoid solving if such an overload has already been found. (cherry picked from commit 7898b5a)
1 parent c7e7e50 commit 8e2f1c5

File tree

2 files changed

+37
-0
lines changed

2 files changed

+37
-0
lines changed

lib/Sema/CSSimplify.cpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11402,6 +11402,7 @@ ConstraintSystem::simplifyApplicableFnConstraint(
1140211402
FunctionType::get(trailingClosureTypes, callAsFunctionResultTy,
1140311403
FunctionType::ExtInfo());
1140411404

11405+
increaseScore(SK_DisfavoredOverload);
1140511406
// Form an unsolved constraint to apply trailing closures to a
1140611407
// callable type produced by `.init`. This constraint would become
1140711408
// active when `callableType` is bound.
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
// RUN: %target-typecheck-verify-swift -target %target-cpu-apple-macosx10.15 -swift-version 5 -debug-constraints > %t.log 2>&1
2+
// RUN: %FileCheck %s < %t.log
3+
4+
// REQUIRES: objc_interop
5+
// REQUIRES: OS=macosx
6+
7+
protocol View {}
8+
protocol Callable {}
9+
10+
struct EmptyView : View {}
11+
12+
@resultBuilder struct ViewBuilder {
13+
static func buildBlock<Content>(_ content: Content) -> Content where Content : View { fatalError() }
14+
}
15+
16+
extension Callable {
17+
func callAsFunction<T: View>(@ViewBuilder _: () -> T) -> some View { EmptyView() }
18+
}
19+
20+
struct MyView<Content> : View {
21+
init(v: Int, @ViewBuilder _: () -> Content) {}
22+
}
23+
24+
extension MyView : Callable where Content == EmptyView {
25+
init(v: Int) {}
26+
}
27+
28+
// CHECK: (overload set choice binding $T6 := (Int) -> MyView<{{.*}}>)
29+
// CHECK-NEXT: (increasing score due to disfavored overload)
30+
// CHECK-NEXT: (solution is worse than the best solution)
31+
32+
func test() -> some View {
33+
return MyView(v: 42) {
34+
return EmptyView()
35+
}
36+
}

0 commit comments

Comments
 (0)