@@ -95,13 +95,26 @@ Substitution Substitution::subst(ModuleDecl *module,
95
95
// conformances from thin air. FIXME: gross.
96
96
if (!conformance &&
97
97
proto->isSpecificProtocol (KnownProtocolKind::AnyObject)) {
98
- auto classDecl
99
- = substReplacement->getClassOrBoundGenericClass ();
100
- assert (classDecl);
101
- SmallVector<ProtocolConformance *, 1 > lookupResults;
102
- classDecl->lookupConformance (classDecl->getParentModule (),
103
- proto, lookupResults);
104
- conformance = ProtocolConformanceRef (lookupResults.front ());
98
+ auto archetype =
99
+ dyn_cast<ArchetypeType>(substReplacement->getCanonicalType ());
100
+ // If classDecl is not nullptr, it is a concrete class.
101
+ auto classDecl = substReplacement->getClassOrBoundGenericClass ();
102
+ if (!classDecl && archetype->getSuperclass ()) {
103
+ // Replacement type is an archetype with a superclass constraint.
104
+ classDecl = archetype->getSuperclass ()->getClassOrBoundGenericClass ();
105
+ assert (classDecl);
106
+ }
107
+ if (classDecl) {
108
+ // Create a concrete conformance based on the conforming class.
109
+ SmallVector<ProtocolConformance *, 1 > lookupResults;
110
+ classDecl->lookupConformance (classDecl->getParentModule (), proto,
111
+ lookupResults);
112
+ conformance = ProtocolConformanceRef (lookupResults.front ());
113
+ } else if (archetype && archetype->requiresClass ()) {
114
+ // Replacement type is an archetype with a class constraint.
115
+ // Create an abstract conformance.
116
+ conformance = ProtocolConformanceRef (proto);
117
+ }
105
118
}
106
119
107
120
assert (conformance);
0 commit comments