Sema: Relax primary associated type matching in matchExistentialTypes()

Recently I found a soundness hole here, where we would allow conversion
between `any P<T>` and `any Q<T>` even if P and Q have different primary
associated types.

However, the fix was too strict, because we still want to allow the
conversion when the associated types have the same name.

Fixes rdar://141968103.
This commit is contained in:
Slava Pestov
2025-01-10 15:32:42 -05:00
parent c17044381e
commit c257cdbc7c
2 changed files with 25 additions and 6 deletions

View File

@@ -4221,7 +4221,7 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
// Finally, check parameterized protocol requirements.
if (!layout.getParameterizedProtocols().empty()) {
SmallVector<std::pair<AssociatedTypeDecl *, Type>, 4> fromReqs;
SmallVector<std::pair<Identifier, Type>, 4> fromReqs;
if (type1->isExistentialType()) {
auto fromLayout = type1->getExistentialLayout();
@@ -4232,8 +4232,7 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
for (unsigned i : indices(argTypes)) {
auto argType = argTypes[i];
auto *assocType = assocTypes[i]->getAssociatedTypeAnchor();
fromReqs.push_back(std::make_pair(assocType, argType));
fromReqs.push_back(std::make_pair(assocTypes[i]->getName(), argType));
}
}
}
@@ -4248,10 +4247,9 @@ ConstraintSystem::matchExistentialTypes(Type type1, Type type2,
for (unsigned i : indices(argTypes)) {
auto argType = argTypes[i];
auto *assocType = assocTypes[i]->getAssociatedTypeAnchor();
bool found = false;
for (auto fromReq : fromReqs) {
if (fromReq.first == assocType) {
if (fromReq.first == assocTypes[i]->getName()) {
// FIXME: Extend the locator path to point to the argument
// inducing the requirement.
auto result = matchTypes(fromReq.second, argType,