@@ -76,8 +76,8 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
7676 return type;
7777 };
7878
79- auto lookupSuperclassConformance = [&](ExistentialLayout &layout ) {
80- if (auto superclass = layout. explicitSuperclass ) {
79+ auto lookupSuperclassConformance = [&](Type superclass ) {
80+ if (superclass) {
8181 if (auto result =
8282 lookupConformance (superclass, protocol, /* allowMissing=*/ false )) {
8383 if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable) &&
@@ -101,7 +101,7 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
101101 auto layout = type->getExistentialLayout ();
102102 if (llvm::all_of (layout.getProtocols (),
103103 [](const auto *P) { return P->isMarkerProtocol (); })) {
104- if (auto conformance = lookupSuperclassConformance (layout)) {
104+ if (auto conformance = lookupSuperclassConformance (layout. explicitSuperclass )) {
105105 return ProtocolConformanceRef (
106106 ctx.getInheritedConformance (type, conformance.getConcrete ()));
107107 }
@@ -113,15 +113,12 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
113113
114114 auto layout = type->getExistentialLayout ();
115115
116- // Due to an IRGen limitation, witness tables cannot be passed from an
117- // existential to an archetype parameter, so for now we restrict this to
118- // @objc protocols and marker protocols .
116+ // If the existential contains non-@objc protocols and the protocol we're
117+ // conforming to needs a witness table, the existential must have a
118+ // self-conformance witness table. For now, Swift.Error is the only one .
119119 if (!layout.isObjC () && !protocol->isMarkerProtocol ()) {
120120 auto constraint = getConstraintType ();
121- // There's a specific exception for protocols with self-conforming
122- // witness tables, but the existential has to be *exactly* that type.
123- // TODO: synthesize witness tables on-demand for protocol compositions
124- // that can satisfy the requirement.
121+ // The existential has to be *exactly* that type.
125122 if (protocol->requiresSelfConformanceWitnessTable () &&
126123 constraint->is <ProtocolType>() &&
127124 constraint->castTo <ProtocolType>()->getDecl () == protocol)
@@ -130,31 +127,23 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
130127 return ProtocolConformanceRef::forInvalid ();
131128 }
132129
133- // If the existential is class-constrained, the class might conform
134- // concretely.
135- if (auto conformance = lookupSuperclassConformance (layout))
136- return conformance;
137-
138- // Otherwise, the existential might conform abstractly.
130+ // The existential might conform abstractly.
139131 for (auto protoDecl : layout.getProtocols ()) {
140-
141132 // If we found the protocol we're looking for, return an abstract
142133 // conformance to it.
143134 if (protoDecl == protocol)
144135 return ProtocolConformanceRef (ctx.getSelfConformance (protocol));
145136
146- // If the protocol has a superclass constraint, we might conform
147- // concretely.
148- if (auto superclass = protoDecl->getSuperclass ()) {
149- if (auto result = lookupConformance (superclass, protocol))
150- return result;
151- }
152-
153137 // Now check refined protocols.
154138 if (protoDecl->inheritsFrom (protocol))
155139 return ProtocolConformanceRef (ctx.getSelfConformance (protocol));
156140 }
157141
142+ // If the existential is class-constrained, the class might conform
143+ // concretely.
144+ if (auto conformance = lookupSuperclassConformance (layout.getSuperclass ()))
145+ return conformance;
146+
158147 // We didn't find our protocol in the existential's list; it doesn't
159148 // conform.
160149 return ProtocolConformanceRef::forInvalid ();
0 commit comments