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(
92159215 }
92169216 }
92179217
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+
92189235 // We've decomposed the types further, so adopt the subflags.
92199236 flags = subflags;
92209237
Original file line number Diff line number Diff line change @@ -230,3 +230,11 @@ do {
230230 func forward< T> ( _ v: T ) -> T { v }
231231 let _: KeyPath < String , Int > = forward ( kp ( ) ) // Ok
232232}
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 {
201201 ( fn as ( ) -> Void ) ( ) // expected-error {{no exact matches in reference to local function 'fn'}}
202202 ( fn_1 as ( ) -> Void ) ( ) // expected-error {{cannot convert value of type '(Bool) -> ()' to type '() -> Void' in coercion}}
203203}
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