20
20
#include " swift/AST/Availability.h"
21
21
#include " swift/AST/Decl.h"
22
22
#include " swift/AST/Module.h"
23
+ #include " swift/AST/PackConformance.h"
24
+ #include " swift/AST/ProtocolConformance.h"
23
25
#include " swift/AST/TypeCheckRequests.h"
24
26
#include " swift/AST/Types.h"
25
27
@@ -44,6 +46,8 @@ ProtocolDecl *ProtocolConformanceRef::getRequirement() const {
44
46
45
47
if (isConcrete ()) {
46
48
return getConcrete ()->getProtocol ();
49
+ } else if (isPack ()) {
50
+ return getPack ()->getProtocol ();
47
51
} else {
48
52
return getAbstract ();
49
53
}
@@ -67,11 +71,14 @@ ProtocolConformanceRef::subst(Type origType,
67
71
if (isInvalid ())
68
72
return *this ;
69
73
70
- // If we have a concrete conformance, we need to substitute the
71
- // conformance to apply to the new type.
72
74
if (isConcrete ())
73
75
return ProtocolConformanceRef (getConcrete ()->subst (subs, conformances,
74
76
options));
77
+ if (isPack ())
78
+ return getPack ()->subst (subs, conformances, options);
79
+
80
+ // Handle abstract conformances below:
81
+
75
82
// If the type is an opaque archetype, the conformance will remain abstract,
76
83
// unless we're specifically substituting opaque types.
77
84
if (auto origArchetype = origType->getAs <ArchetypeType>()) {
@@ -102,17 +109,26 @@ ProtocolConformanceRef::subst(Type origType,
102
109
}
103
110
104
111
ProtocolConformanceRef ProtocolConformanceRef::mapConformanceOutOfContext () const {
105
- if (!isConcrete ())
106
- return *this ;
112
+ if (isConcrete ()) {
113
+ auto *concrete = getConcrete ()->subst (
114
+ [](SubstitutableType *type) -> Type {
115
+ if (auto *archetypeType = type->getAs <ArchetypeType>())
116
+ return archetypeType->getInterfaceType ();
117
+ return type;
118
+ },
119
+ MakeAbstractConformanceForGenericType ());
120
+ return ProtocolConformanceRef (concrete);
121
+ } else if (isPack ()) {
122
+ return getPack ()->subst (
123
+ [](SubstitutableType *type) -> Type {
124
+ if (auto *archetypeType = type->getAs <ArchetypeType>())
125
+ return archetypeType->getInterfaceType ();
126
+ return type;
127
+ },
128
+ MakeAbstractConformanceForGenericType ());
129
+ }
107
130
108
- auto *concrete = getConcrete ()->subst (
109
- [](SubstitutableType *type) -> Type {
110
- if (auto *archetypeType = type->getAs <ArchetypeType>())
111
- return archetypeType->getInterfaceType ();
112
- return type;
113
- },
114
- MakeAbstractConformanceForGenericType ());
115
- return ProtocolConformanceRef (concrete);
131
+ return *this ;
116
132
}
117
133
118
134
Type
@@ -171,6 +187,12 @@ ProtocolConformanceRef::getConditionalRequirements() const {
171
187
172
188
Type ProtocolConformanceRef::getAssociatedType (Type conformingType,
173
189
Type assocType) const {
190
+ if (isPack ()) {
191
+ auto *pack = getPack ();
192
+ assert (conformingType->isEqual (pack->getType ()));
193
+ return pack->getAssociatedType (assocType);
194
+ }
195
+
174
196
assert (!isConcrete () || getConcrete ()->getType ()->isEqual (conformingType));
175
197
176
198
auto type = assocType->getCanonicalType ();
@@ -200,6 +222,14 @@ ProtocolConformanceRef
200
222
ProtocolConformanceRef::getAssociatedConformance (Type conformingType,
201
223
Type assocType,
202
224
ProtocolDecl *protocol) const {
225
+ // If this is a pack conformance, project the associated conformances.
226
+ if (isPack ()) {
227
+ auto *pack = getPack ();
228
+ assert (conformingType->isEqual (pack->getType ()));
229
+ return ProtocolConformanceRef (
230
+ pack->getAssociatedConformance (assocType, protocol));
231
+ }
232
+
203
233
// If this is a concrete conformance, look up the associated conformance.
204
234
if (isConcrete ()) {
205
235
auto conformance = getConcrete ();
@@ -221,23 +251,33 @@ ProtocolConformanceRef::getAssociatedConformance(Type conformingType,
221
251
bool ProtocolConformanceRef::isCanonical () const {
222
252
if (isAbstract () || isInvalid ())
223
253
return true ;
254
+ if (isPack ())
255
+ return getPack ()->isCanonical ();
224
256
return getConcrete ()->isCanonical ();
257
+
225
258
}
226
259
227
260
ProtocolConformanceRef
228
261
ProtocolConformanceRef::getCanonicalConformanceRef () const {
229
262
if (isAbstract () || isInvalid ())
230
263
return *this ;
264
+ if (isPack ())
265
+ return ProtocolConformanceRef (getPack ()->getCanonicalConformance ());
231
266
return ProtocolConformanceRef (getConcrete ()->getCanonicalConformance ());
232
267
}
233
268
234
269
bool ProtocolConformanceRef::hasUnavailableConformance () const {
235
- if (isInvalid ())
270
+ if (isInvalid () || isAbstract () )
236
271
return false ;
237
272
238
- // Abstract conformances are never unavailable.
239
- if (!isConcrete ())
273
+ if (isPack ()) {
274
+ for (auto conformance : getPack ()->getPatternConformances ()) {
275
+ if (conformance.hasUnavailableConformance ())
276
+ return true ;
277
+ }
278
+
240
279
return false ;
280
+ }
241
281
242
282
// Check whether this conformance is on an unavailable extension.
243
283
auto concrete = getConcrete ();
@@ -266,8 +306,17 @@ bool ProtocolConformanceRef::hasMissingConformance(ModuleDecl *module) const {
266
306
bool ProtocolConformanceRef::forEachMissingConformance (
267
307
ModuleDecl *module ,
268
308
llvm::function_ref<bool (BuiltinProtocolConformance *missing)> fn) const {
269
- if (!isConcrete ())
309
+ if (isInvalid () || isAbstract ())
310
+ return false ;
311
+
312
+ if (isPack ()) {
313
+ for (auto conformance : getPack ()->getPatternConformances ()) {
314
+ if (conformance.forEachMissingConformance (module , fn))
315
+ return true ;
316
+ }
317
+
270
318
return false ;
319
+ }
271
320
272
321
// Is this a missing conformance?
273
322
ProtocolConformance *concreteConf = getConcrete ();
@@ -292,6 +341,8 @@ void swift::simple_display(llvm::raw_ostream &out, ProtocolConformanceRef confor
292
341
simple_display (out, conformanceRef.getAbstract ());
293
342
} else if (conformanceRef.isConcrete ()) {
294
343
simple_display (out, conformanceRef.getConcrete ());
344
+ } else if (conformanceRef.isPack ()) {
345
+ simple_display (out, conformanceRef.getPack ());
295
346
}
296
347
}
297
348
0 commit comments