Skip to content

Commit 2bd850c

Browse files
committed
GSB: Fix runaway recursion through EquivalenceClass::lookupNestedType()
We shouldn't generate NestedTypeNameMatch same-type constraints between associated types we haven't realized yet. Otherwise, since maybeResolveEquivalenceClass() can call lookupNestedType() before looking up a PotentialArchetype, it is possible that maybeResolveEquivalenceClass() will return the newly-realized type even when resolutionKind is AlreadyKnown. This can cause an infinite recursion in expandConformanceRequirement(). However, we don't really have to do this here at all, because if a PotentialArchetype is registered with the same name later, we will introduce the same-type constraint in addedNestedType(). It suffices for lookupNestedType() to return the best associated type anchor and ignore the rest. Fixes https://bugs.swift.org/browse/SR-14289 / rdar://problem/74876047.
1 parent f1218fc commit 2bd850c

File tree

2 files changed

+15
-19
lines changed

2 files changed

+15
-19
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 0 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2092,7 +2092,6 @@ TypeDecl *EquivalenceClass::lookupNestedType(
20922092

20932093
// Look for types with the given name in protocols that we know about.
20942094
AssociatedTypeDecl *bestAssocType = nullptr;
2095-
llvm::SmallSetVector<AssociatedTypeDecl *, 4> assocTypeAnchors;
20962095
SmallVector<TypeDecl *, 4> concreteDecls;
20972096
for (const auto &conforms : conformsTo) {
20982097
ProtocolDecl *proto = conforms.first;
@@ -2104,7 +2103,6 @@ TypeDecl *EquivalenceClass::lookupNestedType(
21042103
if (auto assocType = dyn_cast<AssociatedTypeDecl>(member)) {
21052104
// Retrieve the associated type anchor.
21062105
assocType = assocType->getAssociatedTypeAnchor();
2107-
assocTypeAnchors.insert(assocType);
21082106

21092107
if (!bestAssocType ||
21102108
compareAssociatedTypes(assocType, bestAssocType) < 0)
@@ -2131,23 +2129,6 @@ TypeDecl *EquivalenceClass::lookupNestedType(
21312129
lookupConcreteNestedType(decl, name, concreteDecls);
21322130
}
21332131

2134-
// Infer same-type constraints among same-named associated type anchors.
2135-
if (assocTypeAnchors.size() > 1) {
2136-
auto anchorType = getAnchor(builder, builder.getGenericParams());
2137-
auto inferredSource =
2138-
FloatingRequirementSource::forNestedTypeNameMatch(
2139-
assocTypeAnchors.front()->getName());
2140-
for (auto assocType : assocTypeAnchors) {
2141-
if (assocType == bestAssocType) continue;
2142-
2143-
builder.addRequirement(
2144-
Requirement(RequirementKind::SameType,
2145-
DependentMemberType::get(anchorType, bestAssocType),
2146-
DependentMemberType::get(anchorType, assocType)),
2147-
nullptr, inferredSource, nullptr, nullptr);
2148-
}
2149-
}
2150-
21512132
// Form the new cache entry.
21522133
CachedNestedType entry;
21532134
entry.numConformancesPresent = conformsTo.size();

test/Generics/sr14289.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
// RUN: %target-swift-frontend -emit-ir %s
2+
3+
public protocol One {
4+
associatedtype MyType
5+
}
6+
7+
public protocol Two {
8+
associatedtype MyType
9+
}
10+
11+
public protocol Three: One, Two where MyType: Three {}
12+
13+
extension Three {
14+
public func doStuff(_: MyType.MyType.MyType) {}
15+
}

0 commit comments

Comments
 (0)