File tree Expand file tree Collapse file tree 3 files changed +38
-0
lines changed Expand file tree Collapse file tree 3 files changed +38
-0
lines changed Original file line number Diff line number Diff line change @@ -9213,6 +9213,23 @@ ConstraintSystem::simplifyCheckedCastConstraint(
9213
9213
}
9214
9214
}
9215
9215
9216
+ // Peel off marker protocol requirements if this is an existential->concrete
9217
+ // cast. Handles cases like `WritableKeyPath<...> & Sendable as KeyPath`
9218
+ // that require inference which is only attempted if both sides are classes.
9219
+ if (fromType->isExistentialType() && !toType->isExistentialType()) {
9220
+ if (auto *existential = fromType->getAs<ExistentialType>()) {
9221
+ if (auto *PCT = existential->getConstraintType()
9222
+ ->getAs<ProtocolCompositionType>()) {
9223
+ auto newConstraintTy = PCT->withoutMarkerProtocols();
9224
+ if (!newConstraintTy->isEqual(PCT)) {
9225
+ fromType = newConstraintTy->getClassOrBoundGenericClass()
9226
+ ? newConstraintTy
9227
+ : ExistentialType::get(newConstraintTy);
9228
+ }
9229
+ }
9230
+ }
9231
+ }
9232
+
9216
9233
// We've decomposed the types further, so adopt the subflags.
9217
9234
flags = subflags;
9218
9235
Original file line number Diff line number Diff line change @@ -230,3 +230,11 @@ do {
230
230
func forward< T> ( _ v: T ) -> T { v }
231
231
let _: KeyPath < String , Int > = forward ( kp ( ) ) // Ok
232
232
}
233
+
234
+ do {
235
+ final class C < T> {
236
+ let immutable : String = " "
237
+ }
238
+
239
+ _ = \C < Int > . immutable as? ReferenceWritableKeyPath // Ok
240
+ }
Original file line number Diff line number Diff line change @@ -201,3 +201,16 @@ do {
201
201
( fn as ( ) -> Void ) ( ) // expected-error {{no exact matches in reference to local function 'fn'}}
202
202
( fn_1 as ( ) -> Void ) ( ) // expected-error {{cannot convert value of type '(Bool) -> ()' to type '() -> Void' in coercion}}
203
203
}
204
+
205
+ // Test generic parameter inference through casts
206
+ do {
207
+ class A < T> {
208
+ }
209
+
210
+ class B < U> : A < U > {
211
+ }
212
+
213
+ func test( v: any B < Int > & Sendable ) {
214
+ _ = v as A // infers `Int` for `A.T`
215
+ }
216
+ }
You can’t perform that action at this time.
0 commit comments