File tree Expand file tree Collapse file tree 2 files changed +37
-0
lines changed
Expand file tree Collapse file tree 2 files changed +37
-0
lines changed Original file line number Diff line number Diff line change 1515// ===----------------------------------------------------------------------===//
1616#include " swift/Sema/CSBindings.h"
1717#include " TypeChecker.h"
18+ #include " swift/AST/ExistentialLayout.h"
1819#include " swift/AST/GenericEnvironment.h"
1920#include " swift/Sema/ConstraintGraph.h"
2021#include " swift/Sema/ConstraintSystem.h"
@@ -1249,6 +1250,21 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
12491250
12501251 if (TypeVar->getImpl ().isKeyPathType ()) {
12511252 auto objectTy = type->lookThroughAllOptionalTypes ();
1253+
1254+ // If contextual type is an existential with a superclass
1255+ // constraint, let's try to infer a key path type from it.
1256+ if (kind == AllowedBindingKind::Subtypes) {
1257+ if (type->isExistentialType ()) {
1258+ auto layout = type->getExistentialLayout ();
1259+ if (auto superclass = layout.explicitSuperclass ) {
1260+ if (isKnownKeyPathType (superclass)) {
1261+ type = superclass;
1262+ objectTy = superclass;
1263+ }
1264+ }
1265+ }
1266+ }
1267+
12521268 if (!(isKnownKeyPathType (objectTy) || objectTy->is <AnyFunctionType>()))
12531269 return llvm::None;
12541270 }
Original file line number Diff line number Diff line change @@ -1181,3 +1181,24 @@ func f_56854() {
11811181 // expected-note@-1 2 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}
11821182 }
11831183}
1184+
1185+ // rdar://93103421 - Key path type inference doesn't work when the context is an existential type with a key-path superclass
1186+ extension KeyPath : P {
1187+ var member : String { " " }
1188+ }
1189+
1190+ func test_keypath_inference_from_existentials( ) {
1191+ struct A < T> : P {
1192+ var member : String { " a " }
1193+ var other : T { fatalError ( ) }
1194+ }
1195+
1196+ func test< T, U> ( _: any P & KeyPath < A < T > , U > , _: T ) {
1197+ }
1198+
1199+ let _: any P & KeyPath < A < Int > , String > = \. member // Ok
1200+ let _: ( any P & KeyPath < A < Int > , String > ) = \. member // Ok
1201+
1202+ test ( \. other, 42 ) // Ok
1203+ test ( \. member, " " ) // Ok
1204+ }
You can’t perform that action at this time.
0 commit comments