Skip to content

Commit f6254f7

Browse files
committed
[ConstraintSystem] Support existential opening on key path subscript index
1 parent f440dd8 commit f6254f7

File tree

2 files changed

+23
-0
lines changed

2 files changed

+23
-0
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1426,6 +1426,25 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
14261426
return llvm::None;
14271427
}
14281428

1429+
if (TypeVar->getImpl().isKeyPathSubscriptIndex()) {
1430+
// Key path subscript index can only be a r-value non-optional
1431+
// type that is a subtype of a known KeyPath type.
1432+
type = type->getRValueType()->lookThroughAllOptionalTypes();
1433+
1434+
// If argument to a key path subscript is an existential,
1435+
// we can erase it to superclass (if any) here and solver
1436+
// will perform the opening if supertype turns out to be
1437+
// a valid key path type of its subtype.
1438+
if (kind == AllowedBindingKind::Supertypes) {
1439+
if (type->isExistentialType()) {
1440+
type = type->getExistentialLayout().explicitSuperclass;
1441+
}
1442+
}
1443+
1444+
if (!type)
1445+
return llvm::None;
1446+
}
1447+
14291448
if (auto *locator = TypeVar->getImpl().getLocator()) {
14301449
// Don't allow a protocol type to get propagated from the base to the result
14311450
// type of a chain, Result should always be a concrete type which conforms

test/expr/unary/keypath/keypath.swift

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1233,3 +1233,7 @@ func test_keypath_coercion_to_function() {
12331233
let fn = \User.email as (User) -> String // Ok
12341234
_ = users.map(fn) // Ok
12351235
}
1236+
1237+
func test_keypath_application_with_composition(v: String, kp: any KeyPath<String, Int> & PP) {
1238+
_ = v[keyPath: kp] // Ok
1239+
}

0 commit comments

Comments
 (0)