Skip to content

Commit 9314e48

Browse files
committed
[GSB] We don't need an anchor to resolve into an equivalence class.
Any potential archetype with the lowest depth in the equivalence class will do when we're resolving for equivalence classes, so keep the lowest-depth potential archetype handy.
1 parent 801ef51 commit 9314e48

File tree

2 files changed

+30
-16
lines changed

2 files changed

+30
-16
lines changed

include/swift/AST/GenericSignatureBuilder.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,6 +158,10 @@ class GenericSignatureBuilder {
158158
std::vector<Constraint<LayoutConstraint>> layoutConstraints;
159159

160160
/// The members of the equivalence class.
161+
///
162+
/// This list of members is slightly ordered, in that the first
163+
/// element always has a depth no greater than the depth of any other
164+
/// member.
161165
TinyPtrVector<PotentialArchetype *> members;
162166

163167
/// Describes a component within the graph of same-type constraints within
@@ -203,6 +207,9 @@ class GenericSignatureBuilder {
203207
EquivalenceClass &operator=(const EquivalenceClass &) = delete;
204208
EquivalenceClass &operator=(EquivalenceClass &&) = delete;
205209

210+
/// Add a new member to this equivalence class.
211+
void addMember(PotentialArchetype *pa);
212+
206213
/// Record the conformance of this equivalence class to the given
207214
/// protocol as found via the given requirement source.
208215
///
@@ -758,13 +765,11 @@ class GenericSignatureBuilder {
758765
resolvePotentialArchetype(Type type,
759766
ArchetypeResolutionKind resolutionKind);
760767

761-
private:
762768
/// \brief Try to resolvew the equivalence class of the given type.
763769
ResolveResult maybeResolveEquivalenceClass(
764770
Type type,
765771
ArchetypeResolutionKind resolutionKind);
766772

767-
public:
768773
/// \brief Resolve the equivalence class for the given type parameter,
769774
/// which provides information about that type.
770775
///

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 23 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1550,6 +1550,14 @@ unsigned GenericSignatureBuilder::PotentialArchetype::getNestingDepth() const {
15501550
return Depth;
15511551
}
15521552

1553+
void EquivalenceClass::addMember(PotentialArchetype *pa) {
1554+
members.push_back(pa);
1555+
if (members.back()->getNestingDepth() < members.front()->getNestingDepth()) {
1556+
MutableArrayRef<PotentialArchetype *> mutMembers = members;
1557+
std::swap(mutMembers.front(), mutMembers.back());
1558+
}
1559+
}
1560+
15531561
bool EquivalenceClass::recordConformanceConstraint(
15541562
PotentialArchetype *pa,
15551563
ProtocolDecl *proto,
@@ -2759,6 +2767,8 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
27592767
proto, getDependentType(/*genericParams=*/{}),
27602768
ProtocolConformanceRef(proto));
27612769
type = type.subst(subMap, SubstFlags::UseErrorType);
2770+
if (!type)
2771+
type = ErrorType::get(proto->getASTContext());
27622772
} else {
27632773
// Substitute in the superclass type.
27642774
auto superclass = getEquivalenceClassIfPresent()->superclass;
@@ -3095,21 +3105,19 @@ ResolveResult GenericSignatureBuilder::maybeResolveEquivalenceClass(
30953105
}
30963106
}
30973107

3098-
// Retrieve the anchor of the base equivalence class, and use that to
3099-
// find the nested potential archetype corresponding to this dependent
3100-
// type.
3101-
auto baseAnchorPA =
3102-
baseEquivClass->members.front()->getArchetypeAnchor(*this);
3108+
// Retrieve the "smallest" type in the equivalence class, by depth, and
3109+
// use that to find a nested potential archetype. We used the smallest
3110+
// type by depth to limit expansion of the type graph.
3111+
auto basePA = baseEquivClass->members.front();
31033112
auto nestedPA =
3104-
baseAnchorPA->updateNestedTypeForConformance(nestedTypeDecl,
3105-
resolutionKind);
3113+
basePA->updateNestedTypeForConformance(nestedTypeDecl, resolutionKind);
31063114
if (!nestedPA)
31073115
return ResolveResult::forUnresolved(baseEquivClass);
31083116

31093117
// If base resolved to the anchor, then the nested potential archetype
31103118
// we found is the resolved potential archetype. Return it directly,
31113119
// so it doesn't need to be resolved again.
3112-
if (baseAnchorPA == resolvedBase.getAsPotentialArchetype())
3120+
if (basePA == resolvedBase.getAsPotentialArchetype())
31133121
return ResolveResult(nestedPA);
31143122

31153123
// Compute the resolved dependent type to return.
@@ -3978,7 +3986,7 @@ GenericSignatureBuilder::addSameTypeRequirementBetweenArchetypes(
39783986
auto equivClass1Members = equivClass->members;
39793987
auto equivClass2Members = T2->getEquivalenceClassMembers();
39803988
for (auto equiv : equivClass2Members)
3981-
equivClass->members.push_back(equiv);
3989+
equivClass->addMember(equiv);
39823990

39833991
// Grab the old equivalence class, if present. We'll deallocate it at the end.
39843992
auto equivClass2 = T2->getEquivalenceClassIfPresent();
@@ -5656,9 +5664,10 @@ static void collapseSameTypeComponentsThroughDelayedRequirements(
56565664
/// associated, for a type that we haven't tried to resolve yet.
56575665
auto getUnknownTypeVirtualComponent = [&](Type type) {
56585666
if (auto pa =
5659-
builder.resolvePotentialArchetype(type,
5667+
builder.maybeResolveEquivalenceClass(
5668+
type,
56605669
ArchetypeResolutionKind::AlreadyKnown)
5661-
.dyn_cast<PotentialArchetype *>())
5670+
.getAsPotentialArchetype())
56625671
return getPotentialArchetypeVirtualComponent(pa);
56635672

56645673
return getTypeVirtualComponent(type);
@@ -6537,9 +6546,9 @@ GenericSignature *GenericSignatureBuilder::computeRequirementSignature(
65376546
proto->getSelfInterfaceType()->castTo<GenericTypeParamType>();
65386547
builder.addGenericParameter(selfType);
65396548
auto selfPA =
6540-
builder.resolvePotentialArchetype(selfType,
6541-
ArchetypeResolutionKind::WellFormed)
6542-
.get<PotentialArchetype *>();
6549+
builder.resolveEquivalenceClass(selfType,
6550+
ArchetypeResolutionKind::WellFormed)
6551+
->members.front();
65436552

65446553
// Add the conformance of 'self' to the protocol.
65456554
auto requirement =

0 commit comments

Comments
 (0)