@@ -76,8 +76,8 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
76
76
return type;
77
77
};
78
78
79
- auto lookupSuperclassConformance = [&](ExistentialLayout &layout ) {
80
- if (auto superclass = layout. explicitSuperclass ) {
79
+ auto lookupSuperclassConformance = [&](Type superclass ) {
80
+ if (superclass) {
81
81
if (auto result =
82
82
lookupConformance (superclass, protocol, /* allowMissing=*/ false )) {
83
83
if (protocol->isSpecificProtocol (KnownProtocolKind::Sendable) &&
@@ -101,7 +101,7 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
101
101
auto layout = type->getExistentialLayout ();
102
102
if (llvm::all_of (layout.getProtocols (),
103
103
[](const auto *P) { return P->isMarkerProtocol (); })) {
104
- if (auto conformance = lookupSuperclassConformance (layout)) {
104
+ if (auto conformance = lookupSuperclassConformance (layout. explicitSuperclass )) {
105
105
return ProtocolConformanceRef (
106
106
ctx.getInheritedConformance (type, conformance.getConcrete ()));
107
107
}
@@ -113,15 +113,12 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
113
113
114
114
auto layout = type->getExistentialLayout ();
115
115
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 .
119
119
if (!layout.isObjC () && !protocol->isMarkerProtocol ()) {
120
120
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.
125
122
if (protocol->requiresSelfConformanceWitnessTable () &&
126
123
constraint->is <ProtocolType>() &&
127
124
constraint->castTo <ProtocolType>()->getDecl () == protocol)
@@ -130,31 +127,23 @@ ModuleDecl::lookupExistentialConformance(Type type, ProtocolDecl *protocol) {
130
127
return ProtocolConformanceRef::forInvalid ();
131
128
}
132
129
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.
139
131
for (auto protoDecl : layout.getProtocols ()) {
140
-
141
132
// If we found the protocol we're looking for, return an abstract
142
133
// conformance to it.
143
134
if (protoDecl == protocol)
144
135
return ProtocolConformanceRef (ctx.getSelfConformance (protocol));
145
136
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
-
153
137
// Now check refined protocols.
154
138
if (protoDecl->inheritsFrom (protocol))
155
139
return ProtocolConformanceRef (ctx.getSelfConformance (protocol));
156
140
}
157
141
142
+ // If the existential is class-constrained, the class might conform
143
+ // concretely.
144
+ if (auto conformance = lookupSuperclassConformance (layout.getSuperclass ()))
145
+ return conformance;
146
+
158
147
// We didn't find our protocol in the existential's list; it doesn't
159
148
// conform.
160
149
return ProtocolConformanceRef::forInvalid ();
0 commit comments