@@ -591,10 +591,10 @@ bool RequirementSource::isAcceptableStorageKind(Kind kind,
591
591
case Superclass:
592
592
case Concrete:
593
593
switch (storageKind) {
594
+ case StorageKind::StoredType:
594
595
case StorageKind::ProtocolConformance:
595
596
return true ;
596
597
597
- case StorageKind::StoredType:
598
598
case StorageKind::AssociatedTypeDecl:
599
599
case StorageKind::None:
600
600
return false ;
@@ -1043,6 +1043,17 @@ const RequirementSource *RequirementSource::viaConcrete(
1043
1043
0 , WrittenRequirementLoc ());
1044
1044
}
1045
1045
1046
+ const RequirementSource *RequirementSource::viaConcrete (
1047
+ GenericSignatureBuilder &builder,
1048
+ Type existentialType) const {
1049
+ assert (existentialType->isExistentialType ());
1050
+ REQUIREMENT_SOURCE_FACTORY_BODY (
1051
+ (nodeID, Concrete, this , existentialType.getPointer (),
1052
+ nullptr , nullptr ),
1053
+ (Concrete, this , existentialType),
1054
+ 0 , WrittenRequirementLoc ());
1055
+ }
1056
+
1046
1057
const RequirementSource *RequirementSource::viaParent (
1047
1058
GenericSignatureBuilder &builder,
1048
1059
AssociatedTypeDecl *assocType) const {
@@ -1115,8 +1126,14 @@ const RequirementSource *RequirementSource::withoutRedundantSubpath(
1115
1126
getWrittenRequirementLoc ());
1116
1127
1117
1128
case Concrete:
1118
- return parent->withoutRedundantSubpath (builder, start, end)
1119
- ->viaConcrete (builder, getProtocolConformance ());
1129
+ if (auto existentialType = getStoredType ()) {
1130
+ assert (existentialType->isExistentialType ());
1131
+ return parent->withoutRedundantSubpath (builder, start, end)
1132
+ ->viaConcrete (builder, existentialType);
1133
+ } else {
1134
+ return parent->withoutRedundantSubpath (builder, start, end)
1135
+ ->viaConcrete (builder, getProtocolConformance ());
1136
+ }
1120
1137
1121
1138
case Layout:
1122
1139
return parent->withoutRedundantSubpath (builder, start, end)
@@ -2307,11 +2324,30 @@ GenericSignatureBuilder::resolveConcreteConformance(ResolvedType type,
2307
2324
return nullptr ;
2308
2325
}
2309
2326
2310
- concreteSource = concreteSource->viaConcrete (*this , conformance);
2311
- equivClass->recordConformanceConstraint (*this , type, proto, concreteSource);
2312
- if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2313
- concreteSource->getLoc ()))
2314
- return nullptr ;
2327
+ if (concrete->isExistentialType ()) {
2328
+ // If we have an existential type, record the original type, and
2329
+ // not the conformance.
2330
+ //
2331
+ // The conformance must be a self-conformance, and self-conformances
2332
+ // do not record the original type in the case where a derived
2333
+ // protocol self-conforms to a base protocol; for example:
2334
+ //
2335
+ // @objc protocol Base {}
2336
+ //
2337
+ // @objc protocol Derived {}
2338
+ //
2339
+ // struct S<T : Base> {}
2340
+ //
2341
+ // extension S where T == Derived {}
2342
+ assert (isa<SelfProtocolConformance>(conformance.getConcrete ()));
2343
+ concreteSource = concreteSource->viaConcrete (*this , concrete);
2344
+ } else {
2345
+ concreteSource = concreteSource->viaConcrete (*this , conformance);
2346
+ equivClass->recordConformanceConstraint (*this , type, proto, concreteSource);
2347
+ if (addConditionalRequirements (conformance, /* inferForModule=*/ nullptr ,
2348
+ concreteSource->getLoc ()))
2349
+ return nullptr ;
2350
+ }
2315
2351
2316
2352
return concreteSource;
2317
2353
}
@@ -2329,6 +2365,8 @@ const RequirementSource *GenericSignatureBuilder::resolveSuperConformance(
2329
2365
if (conformance.isInvalid ())
2330
2366
return nullptr ;
2331
2367
2368
+ assert (!conformance.isAbstract ());
2369
+
2332
2370
// Conformance to this protocol is redundant; update the requirement source
2333
2371
// appropriately.
2334
2372
const RequirementSource *superclassSource;
@@ -2526,10 +2564,11 @@ static void concretizeNestedTypeFromConcreteParent(
2526
2564
conformance.getConcrete ()->getTypeWitness (assocType);
2527
2565
if (!witnessType)
2528
2566
return ; // FIXME: should we delay here?
2529
- } else if (auto archetype = concreteParent->getAs <ArchetypeType>()) {
2530
- witnessType = archetype->getNestedType (assocType->getName ());
2531
2567
} else {
2532
- witnessType = DependentMemberType::get (concreteParent, assocType);
2568
+ // Otherwise we have an abstract conformance to an opaque result type.
2569
+ assert (conformance.isAbstract ());
2570
+ auto archetype = concreteParent->castTo <ArchetypeType>();
2571
+ witnessType = archetype->getNestedType (assocType->getName ());
2533
2572
}
2534
2573
2535
2574
builder.addSameTypeRequirement (
@@ -2549,8 +2588,7 @@ PotentialArchetype *PotentialArchetype::updateNestedTypeForConformance(
2549
2588
2550
2589
Identifier name = assocType->getName ();
2551
2590
2552
- // Look for either an unresolved potential archetype (which we can resolve
2553
- // now) or a potential archetype with the appropriate associated type.
2591
+ // Look for a potential archetype with the appropriate associated type.
2554
2592
PotentialArchetype *resultPA = nullptr ;
2555
2593
auto knownNestedTypes = NestedTypes.find (name);
2556
2594
bool shouldUpdatePA = false ;
0 commit comments