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 15
15
// ===----------------------------------------------------------------------===//
16
16
#include " swift/Sema/CSBindings.h"
17
17
#include " TypeChecker.h"
18
+ #include " swift/AST/ExistentialLayout.h"
18
19
#include " swift/AST/GenericEnvironment.h"
19
20
#include " swift/Sema/ConstraintGraph.h"
20
21
#include " swift/Sema/ConstraintSystem.h"
@@ -1249,6 +1250,21 @@ PotentialBindings::inferFromRelational(Constraint *constraint) {
1249
1250
1250
1251
if (TypeVar->getImpl ().isKeyPathType ()) {
1251
1252
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
+
1252
1268
if (!(isKnownKeyPathType (objectTy) || objectTy->is <AnyFunctionType>()))
1253
1269
return llvm::None;
1254
1270
}
Original file line number Diff line number Diff line change @@ -1181,3 +1181,24 @@ func f_56854() {
1181
1181
// expected-note@-1 2 {{cast 'Any' to 'AnyObject' or use 'as!' to force downcast to a more specific type to access members}}
1182
1182
}
1183
1183
}
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