Skip to content

Commit cdd8166

Browse files
committed
[CSBindings] Don't favor unresolved key path type over a conjunction
If key path capability is not yet determined it cannot be favored over a conjunction because: 1. There could be no other bindings and that would mean that key path would be selected even though it's not yet ready. 2. A conjunction could be the source of type context for the key path. Resolves: rdar://119055010
1 parent 144ede7 commit cdd8166

File tree

2 files changed

+51
-0
lines changed

2 files changed

+51
-0
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1320,6 +1320,14 @@ bool BindingSet::favoredOverConjunction(Constraint *conjunction) const {
13201320
}
13211321
}
13221322

1323+
// If key path capability is not yet determined it cannot be favored
1324+
// over a conjunction because:
1325+
// 1. There could be no other bindings and that would mean that
1326+
// key path would be selected even though it's not yet ready.
1327+
// 2. A conjunction could be the source of type context for the key path.
1328+
if (TypeVar->getImpl().isKeyPathType() && isDelayed())
1329+
return false;
1330+
13231331
return true;
13241332
}
13251333

test/Constraints/rdar119055010.swift

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// RUN: %target-typecheck-verify-swift
2+
3+
// rdar://119055010 - greedy key path type assignment breaks keypath-to-function conversion
4+
5+
protocol Executable {}
6+
7+
final class Wrapper<Value> {
8+
func update<Return>(_ work: (inout Value) throws -> Return) rethrows -> Return {
9+
fatalError()
10+
}
11+
}
12+
13+
enum Lookup<Value> {
14+
func flatMap<T>(_ transform: (Value) throws -> Lookup<T>) rethrows -> Lookup<T> { fatalError() }
15+
}
16+
17+
protocol Entry {
18+
}
19+
20+
extension Entry {
21+
var executable: Lookup<any Executable> {
22+
fatalError()
23+
}
24+
}
25+
26+
func lookup() -> Lookup<any Entry> {
27+
fatalError()
28+
}
29+
30+
struct Test {
31+
struct Data {
32+
}
33+
34+
let value = Wrapper<Data>()
35+
36+
func run() -> Lookup<any Executable> {
37+
value.update { data in
38+
let _ = 42
39+
return lookup()
40+
}
41+
.flatMap(\.executable)
42+
}
43+
}

0 commit comments

Comments
 (0)