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 @@ -9215,6 +9215,23 @@ ConstraintSystem::simplifyCheckedCastConstraint(
9215
9215
}
9216
9216
}
9217
9217
9218
+ // Peel off marker protocol requirements if this is an existential->concrete
9219
+ // cast. Handles cases like `WritableKeyPath<...> & Sendable as KeyPath`
9220
+ // that require inference which is only attempted if both sides are classes.
9221
+ if (fromType->isExistentialType() && !toType->isExistentialType()) {
9222
+ if (auto *existential = fromType->getAs<ExistentialType>()) {
9223
+ if (auto *PCT = existential->getConstraintType()
9224
+ ->getAs<ProtocolCompositionType>()) {
9225
+ auto newConstraintTy = PCT->withoutMarkerProtocols();
9226
+ if (!newConstraintTy->isEqual(PCT)) {
9227
+ fromType = newConstraintTy->getClassOrBoundGenericClass()
9228
+ ? newConstraintTy
9229
+ : ExistentialType::get(newConstraintTy);
9230
+ }
9231
+ }
9232
+ }
9233
+ }
9234
+
9218
9235
// We've decomposed the types further, so adopt the subflags.
9219
9236
flags = subflags;
9220
9237
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