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(
92139213 }
92149214 }
92159215
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+
92169233 // We've decomposed the types further, so adopt the subflags.
92179234 flags = subflags;
92189235
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