mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
Sema: Fix deep equality matching for parameterized protocol types
Fixes rdar://problem/98356057.
This commit is contained in:
@@ -3286,7 +3286,41 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
|
||||
}
|
||||
|
||||
// Handle existential types.
|
||||
if (type1->isExistentialType() && type2->isExistentialType()) {
|
||||
if (auto *existential1 = type1->getAs<ExistentialType>()) {
|
||||
auto existential2 = type2->castTo<ExistentialType>();
|
||||
|
||||
auto result = matchTypes(existential1->getConstraintType(),
|
||||
existential2->getConstraintType(),
|
||||
ConstraintKind::Bind, subflags,
|
||||
locator.withPathElement(
|
||||
ConstraintLocator::ExistentialConstraintType));
|
||||
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
|
||||
return getTypeMatchSuccess();
|
||||
}
|
||||
|
||||
// Arguments of parameterized protocol types have to match on the nose.
|
||||
if (auto ppt1 = type1->getAs<ParameterizedProtocolType>()) {
|
||||
auto ppt2 = type2->castTo<ParameterizedProtocolType>();
|
||||
|
||||
auto result = matchTypes(ppt1->getBaseType(),
|
||||
ppt2->getBaseType(),
|
||||
ConstraintKind::Bind, subflags,
|
||||
locator.withPathElement(
|
||||
ConstraintLocator::ParentType));
|
||||
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
|
||||
return matchDeepTypeArguments(*this, subflags,
|
||||
ppt1->getArgs(),
|
||||
ppt2->getArgs(),
|
||||
locator);
|
||||
}
|
||||
|
||||
if (type1->isExistentialType()) {
|
||||
auto layout1 = type1->getExistentialLayout();
|
||||
auto layout2 = type2->getExistentialLayout();
|
||||
|
||||
@@ -3309,24 +3343,16 @@ ConstraintSystem::matchDeepEqualityTypes(Type type1, Type type2,
|
||||
if (!layout1.explicitSuperclass || !layout2.explicitSuperclass)
|
||||
return getTypeMatchFailure(locator);
|
||||
|
||||
auto subLocator = locator.withPathElement(
|
||||
ConstraintLocator::ProtocolCompositionSuperclassType);
|
||||
auto result = matchTypes(layout1.explicitSuperclass,
|
||||
layout2.explicitSuperclass,
|
||||
ConstraintKind::Bind, subflags,
|
||||
locator.withPathElement(
|
||||
ConstraintLocator::ExistentialSuperclassType));
|
||||
subLocator);
|
||||
if (result.isFailure())
|
||||
return result;
|
||||
}
|
||||
|
||||
// Arguments of parameterized protocol types have to match on the nose.
|
||||
if (auto ppt1 = type1->getAs<ParameterizedProtocolType>()) {
|
||||
auto ppt2 = type2->castTo<ParameterizedProtocolType>();
|
||||
return matchDeepTypeArguments(*this, subflags,
|
||||
ppt1->getArgs(),
|
||||
ppt2->getArgs(),
|
||||
locator);
|
||||
}
|
||||
|
||||
return getTypeMatchSuccess();
|
||||
}
|
||||
|
||||
@@ -6367,7 +6393,8 @@ ConstraintSystem::matchTypes(Type type1, Type type2, ConstraintKind kind,
|
||||
// If we are matching types for equality, we might still have
|
||||
// type variables inside the protocol composition's superclass
|
||||
// constraint.
|
||||
conversionsOrFixes.push_back(ConversionRestrictionKind::DeepEquality);
|
||||
if (desugar1->getKind() == desugar2->getKind())
|
||||
conversionsOrFixes.push_back(ConversionRestrictionKind::DeepEquality);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
||||
Reference in New Issue
Block a user