Skip to content

Commit e65f74d

Browse files
committed
[GSB] Infer same-type constraints among same-named associated types.
When we have an equivalence class that contains two unrelated associated types with the same name, infer a same-type constraint between those two associated types. This is a more principled way to introduce these constraints that we had before, fixing a recently-introduced regression.
1 parent 3cdf7cc commit e65f74d

File tree

2 files changed

+19
-2
lines changed

2 files changed

+19
-2
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1662,6 +1662,7 @@ TypeDecl *EquivalenceClass::lookupNestedType(
16621662

16631663
// Look for types with the given name in protocols that we know about.
16641664
AssociatedTypeDecl *bestAssocType = nullptr;
1665+
llvm::SmallSetVector<AssociatedTypeDecl *, 4> assocTypeAnchors;
16651666
SmallVector<TypeDecl *, 4> concreteDecls;
16661667
for (const auto &conforms : conformsTo) {
16671668
ProtocolDecl *proto = conforms.first;
@@ -1674,6 +1675,7 @@ TypeDecl *EquivalenceClass::lookupNestedType(
16741675
if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
16751676
// Retrieve the associated type anchor.
16761677
assocType = assocType->getAssociatedTypeAnchor();
1678+
assocTypeAnchors.insert(assocType);
16771679

16781680
if (!bestAssocType ||
16791681
compareAssociatedTypes(assocType, bestAssocType) < 0)
@@ -1731,6 +1733,22 @@ TypeDecl *EquivalenceClass::lookupNestedType(
17311733
}
17321734
}
17331735

1736+
// Infer same-type constraints among same-named associated type anchors.
1737+
if (assocTypeAnchors.size() > 1) {
1738+
auto &builder = *members.front()->getBuilder();
1739+
auto anchorType = getAnchor({ });
1740+
auto inferredSource = FloatingRequirementSource::forInferred(nullptr);
1741+
for (auto assocType : assocTypeAnchors) {
1742+
if (assocType == bestAssocType) continue;
1743+
1744+
builder.addRequirement(
1745+
Requirement(RequirementKind::SameType,
1746+
DependentMemberType::get(anchorType, bestAssocType),
1747+
DependentMemberType::get(anchorType, assocType)),
1748+
inferredSource, nullptr);
1749+
}
1750+
}
1751+
17341752
// Form the new cache entry.
17351753
CachedNestedType entry;
17361754
entry.numConformancesPresent = conformsTo.size();

test/Generics/requirement_inference.swift

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -154,8 +154,7 @@ protocol P10 {
154154
}
155155

156156
// CHECK-LABEL: sameTypeConcrete1@
157-
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == X3, τ_0_0.B == Int, τ_0_0.C == Int>
158-
// FIXME: Should have a second τ_0_0.A == X3
157+
// CHECK: Canonical generic signature: <τ_0_0 where τ_0_0 : P10, τ_0_0 : P9, τ_0_0.A == X3, τ_0_0.A == X3, τ_0_0.B == Int, τ_0_0.C == Int>
159158
func sameTypeConcrete1<T : P9 & P10>(_: T) where T.A == X3, T.C == T.B, T.C == Int { }
160159

161160
// CHECK-LABEL: sameTypeConcrete2@

0 commit comments

Comments
 (0)