Skip to content

Commit 0f0a590

Browse files
committed
[GSB] Put conformance requirements on the proper potential archetype.
We were putting conformance requirements on the representative of the equivalence class, rather than directly on the potential archetype on which the conformance requirement was specified. This violates the invariant used when forming protocol-requirement sources that we never reseat a requirement onto the representative (which would have become a problem when implementing recursive protocol constreaints) as well as masking a GSB idempotency issue that comes from same-type requirements where the right-hand side was not guaranteed to refer to the archetype anchor *within* that subcomponent.
1 parent 5b4f2e6 commit 0f0a590

File tree

2 files changed

+41
-10
lines changed

2 files changed

+41
-10
lines changed

lib/AST/GenericSignatureBuilder.cpp

Lines changed: 40 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1516,6 +1516,18 @@ PotentialArchetype *PotentialArchetype::getNestedArchetypeAnchor(
15161516
NestedTypeUpdate::AddIfMissing);
15171517
}
15181518

1519+
// If we have an associated type, drop any typealiases that aren't in
1520+
// the same module as the protocol.
1521+
// FIXME: This is an unprincipled hack for an unprincipled feature.
1522+
typealiases.erase(
1523+
std::remove_if(typealiases.begin(), typealiases.end(),
1524+
[&](TypeAliasDecl *typealias) {
1525+
return typealias->getParentModule() !=
1526+
typealias->getDeclContext()
1527+
->getAsNominalTypeOrNominalTypeExtensionContext()->getParentModule();
1528+
}),
1529+
typealiases.end());
1530+
15191531
// Update for all of the typealiases with this name, which will introduce
15201532
// various same-type constraints.
15211533
for (auto typealias : typealiases) {
@@ -2232,17 +2244,14 @@ ConstraintResult GenericSignatureBuilder::addConformanceRequirement(
22322244
return ConstraintResult::Conflicting;
22332245
}
22342246

2235-
// Add the requirement to the representative.
2236-
auto T = PAT->getRepresentative();
2237-
22382247
bool inserted = Visited.insert(Proto).second;
22392248
assert(inserted);
22402249
(void) inserted;
22412250
SWIFT_DEFER {
22422251
Visited.erase(Proto);
22432252
};
22442253

2245-
auto concreteSelf = T->getDependentType({}, /*allowUnresolved=*/true);
2254+
auto concreteSelf = PAT->getDependentType({}, /*allowUnresolved=*/true);
22462255
auto protocolSubMap = SubstitutionMap::getProtocolSubstitutions(
22472256
Proto, concreteSelf, ProtocolConformanceRef(Proto));
22482257

@@ -2285,7 +2294,7 @@ ConstraintResult GenericSignatureBuilder::addConformanceRequirement(
22852294
for (auto Member : getProtocolMembers(Proto)) {
22862295
if (auto AssocType = dyn_cast<AssociatedTypeDecl>(Member)) {
22872296
// Add requirements placed directly on this associated type.
2288-
auto AssocPA = T->getNestedType(AssocType, *this);
2297+
auto AssocPA = PAT->getNestedType(AssocType, *this);
22892298

22902299
auto assocResult =
22912300
addInheritedRequirements(AssocType, AssocPA, Source, Visited);
@@ -3804,6 +3813,18 @@ namespace swift {
38043813
}
38053814
}
38063815

3816+
/// Retrieve the "local" archetype anchor for the given potential archetype,
3817+
/// which rebuilds this potential archetype using the archetype anchors of
3818+
/// the parent types.
3819+
static PotentialArchetype *getLocalAnchor(PotentialArchetype *pa,
3820+
GenericSignatureBuilder &builder) {
3821+
auto parent = pa->getParent();
3822+
if (!parent) return pa;
3823+
3824+
auto parentAnchor = getLocalAnchor(parent, builder);
3825+
return parentAnchor->getNestedArchetypeAnchor(pa->getNestedName(), builder);
3826+
}
3827+
38073828
/// Computes the ordered set of archetype anchors required to form a minimum
38083829
/// spanning tree among the connected components formed by only the derived
38093830
/// same-type requirements within the equivalence class of \c rep.
@@ -3842,8 +3863,10 @@ namespace swift {
38423863
/// canonical edges connects vertex i to vertex i+1 for i in 0..<size-1.
38433864
static void computeDerivedSameTypeComponents(
38443865
PotentialArchetype *rep,
3845-
std::vector<DerivedSameTypeComponent> &components,
38463866
llvm::SmallDenseMap<PotentialArchetype *, unsigned> &componentOf){
3867+
// Perform a depth-first search to identify the components.
3868+
auto equivClass = rep->getOrCreateEquivalenceClass();
3869+
auto &components = equivClass->derivedSameTypeComponents;
38473870
for (auto pa : rep->getEquivalenceClassMembers()) {
38483871
// If we've already seen this potential archetype, there's nothing else to
38493872
// do.
@@ -3858,7 +3881,6 @@ static void computeDerivedSameTypeComponents(
38583881

38593882
// If there is a concrete type, figure out the best concrete type anchor
38603883
// per component.
3861-
auto equivClass = rep->getOrCreateEquivalenceClass();
38623884
for (const auto &concrete : equivClass->concreteTypeConstraints) {
38633885
// Dig out the component associated with constraint.
38643886
assert(componentOf.count(concrete.archetype) > 0);
@@ -3917,6 +3939,16 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
39173939
if (!equivClass || !equivClass->derivedSameTypeComponents.empty())
39183940
return;
39193941

3942+
// Make sure that we've build the archetype anchors for each potential
3943+
// archetype in this equivalence class. This is important to do for *all*
3944+
// potential archetypes because some non-archetype anchors will nonetheless
3945+
// be used in the canonicalized requirements.
3946+
for (auto pa : pa->getEquivalenceClassMembers()) {
3947+
(void)getLocalAnchor(pa, *this);
3948+
}
3949+
equivClass = pa->getEquivalenceClassIfPresent();
3950+
assert(equivClass && "Equivalence class disappeared?");
3951+
39203952
for (auto &entry : equivClass->sameTypeConstraints) {
39213953
auto &constraints = entry.second;
39223954

@@ -3938,8 +3970,7 @@ void GenericSignatureBuilder::checkSameTypeConstraints(
39383970
// Compute the components in the subgraph of the same-type constraint graph
39393971
// that includes only derived constraints.
39403972
llvm::SmallDenseMap<PotentialArchetype *, unsigned> componentOf;
3941-
computeDerivedSameTypeComponents(pa, equivClass->derivedSameTypeComponents,
3942-
componentOf);
3973+
computeDerivedSameTypeComponents(pa, componentOf);
39433974

39443975
// Go through all of the same-type constraints, collecting all of the
39453976
// non-derived constraints to put them into bins: intra-component and

validation-test/compiler_crashers/28730-unreachable-executed-at-swift-lib-ast-astcontext-cpp-1229.swift renamed to validation-test/compiler_crashers_fixed/28730-unreachable-executed-at-swift-lib-ast-astcontext-cpp-1229.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,5 +5,5 @@
55
// See https://swift.org/LICENSE.txt for license information
66
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
77

8-
// RUN: not --crash %target-swift-frontend %s -emit-ir
8+
// RUN: not %target-swift-frontend %s -emit-ir
99
class a=protocol P{{}typealias e:P}}extension P{func a{}typealias e:a

0 commit comments

Comments
 (0)