[CSSimplify] Allow type inference through marker protocol existential casts

```swift
class A<T> {
}

class B<U> : A<U> {
}

func test(v: any B<Int> & Sendable) {
  _ = v as A // infers `Int` for `A.T`
}
```
This commit is contained in:
Pavel Yaskevich
2024-03-11 10:16:27 -07:00
parent b17f0b534c
commit 681d1605af
3 changed files with 38 additions and 0 deletions

View File

@@ -9215,6 +9215,23 @@ ConstraintSystem::simplifyCheckedCastConstraint(
}
}
// Peel off marker protocol requirements if this is an existential->concrete
// cast. Handles cases like `WritableKeyPath<...> & Sendable as KeyPath`
// that require inference which is only attempted if both sides are classes.
if (fromType->isExistentialType() && !toType->isExistentialType()) {
if (auto *existential = fromType->getAs<ExistentialType>()) {
if (auto *PCT = existential->getConstraintType()
->getAs<ProtocolCompositionType>()) {
auto newConstraintTy = PCT->withoutMarkerProtocols();
if (!newConstraintTy->isEqual(PCT)) {
fromType = newConstraintTy->getClassOrBoundGenericClass()
? newConstraintTy
: ExistentialType::get(newConstraintTy);
}
}
}
}
// We've decomposed the types further, so adopt the subflags.
flags = subflags;