@@ -262,16 +262,13 @@ static llvm::Value *bindWitnessTableAtIndex(IRGenFunction &IGF,
262
262
}
263
263
264
264
struct OpenedElementContext {
265
- GenericEnvironment *packEnvironment;
266
- CanGenericSignature packSignature;
267
-
268
- GenericEnvironment *elementEnvironment;
269
- CanGenericSignature elementSignature;
265
+ GenericEnvironment *environment;
266
+ CanGenericSignature signature;
270
267
271
268
static OpenedElementContext
272
269
createForPackExpansion (IRGenFunction &IGF, CanPackExpansionType expansionTy) {
273
270
// Get the outer generic signature and environment.
274
- auto *genericEnv = cast<PackArchetypeType >(expansionTy.getCountType ())
271
+ auto *genericEnv = cast<ArchetypeType >(expansionTy.getCountType ())
275
272
->getGenericEnvironment ();
276
273
auto subMap = genericEnv->getForwardingSubstitutionMap ();
277
274
@@ -282,15 +279,15 @@ struct OpenedElementContext {
282
279
auto *elementEnv = GenericEnvironment::forOpenedElement (
283
280
elementSig, UUID::fromTime (), expansionTy.getCountType (), subMap);
284
281
285
- return {genericEnv, genericSig, elementEnv, elementSig};
282
+ return {elementEnv, elementSig};
286
283
}
287
284
};
288
285
289
286
static void bindElementSignatureRequirementsAtIndex (
290
287
IRGenFunction &IGF, OpenedElementContext const &context, llvm::Value *index,
291
288
DynamicMetadataRequest request) {
292
289
enumerateGenericSignatureRequirements (
293
- context.elementSignature , [&](GenericRequirement requirement) {
290
+ context.signature , [&](GenericRequirement requirement) {
294
291
switch (requirement.getKind ()) {
295
292
case GenericRequirement::Kind::Shape:
296
293
case GenericRequirement::Kind::Metadata:
@@ -299,12 +296,12 @@ static void bindElementSignatureRequirementsAtIndex(
299
296
case GenericRequirement::Kind::MetadataPack: {
300
297
auto ty = requirement.getTypeParameter ();
301
298
auto patternPackArchetype = cast<PackArchetypeType>(
302
- context.packEnvironment -> mapTypeIntoContext (ty)
299
+ context.environment -> maybeApplyOuterContextSubstitutions (ty)
303
300
->getCanonicalType ());
304
301
auto response =
305
302
IGF.emitTypeMetadataRef (patternPackArchetype, request);
306
303
auto elementArchetype =
307
- context.elementEnvironment
304
+ context.environment
308
305
->mapPackTypeIntoElementContext (
309
306
patternPackArchetype->getInterfaceType ())
310
307
->getCanonicalType ();
@@ -319,20 +316,20 @@ static void bindElementSignatureRequirementsAtIndex(
319
316
auto ty = requirement.getTypeParameter ();
320
317
auto proto = requirement.getProtocol ();
321
318
auto patternPackArchetype = cast<PackArchetypeType>(
322
- context.packEnvironment -> mapTypeIntoContext (ty)
319
+ context.environment -> maybeApplyOuterContextSubstitutions (ty)
323
320
->getCanonicalType ());
324
321
auto elementArchetype =
325
- context.elementEnvironment
322
+ context.environment
326
323
->mapPackTypeIntoElementContext (
327
324
patternPackArchetype->getInterfaceType ())
328
325
->getCanonicalType ();
329
326
llvm::Value *_metadata = nullptr ;
330
327
auto packConformance =
331
- context.packSignature ->lookupConformance (ty, proto);
328
+ context.signature ->lookupConformance (ty, proto);
332
329
auto *wtablePack = emitWitnessTableRef (IGF, patternPackArchetype,
333
330
&_metadata, packConformance);
334
331
auto elementConformance =
335
- context.elementSignature ->lookupConformance (ty, proto);
332
+ context.signature ->lookupConformance (ty, proto);
336
333
auto *wtable = bindWitnessTableAtIndex (
337
334
IGF, elementArchetype, elementConformance, wtablePack, index);
338
335
assert (wtable);
@@ -350,7 +347,7 @@ static llvm::Value *emitPackExpansionElementMetadata(
350
347
351
348
// Replace pack archetypes with element archetypes in the pattern type.
352
349
auto instantiatedPatternTy =
353
- context.elementEnvironment
350
+ context.environment
354
351
->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
355
352
->getCanonicalType ();
356
353
@@ -526,11 +523,11 @@ static llvm::Value *emitPackExpansionElementWitnessTable(
526
523
527
524
// Replace pack archetypes with element archetypes in the pattern type.
528
525
auto instantiatedPatternTy =
529
- context.elementEnvironment
526
+ context.environment
530
527
->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
531
528
->getCanonicalType ();
532
529
auto instantiatedConformance =
533
- context.elementEnvironment ->getGenericSignature ()->lookupConformance (
530
+ context.environment ->getGenericSignature ()->lookupConformance (
534
531
instantiatedPatternTy, conformance.getRequirement ());
535
532
536
533
// Emit the element witness table.
@@ -646,7 +643,7 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
646
643
ArrayRef<ProtocolDecl *> protocols, llvm::Value *index,
647
644
DynamicMetadataRequest request,
648
645
llvm::SmallVectorImpl<llvm::Value *> &wtables) {
649
- // If the packs have already been materialized, just gep into it .
646
+ // If the packs have already been materialized, just gep into them .
650
647
auto materializedMetadataPack =
651
648
tryGetLocalPackTypeMetadata (IGF, packType, request);
652
649
llvm::SmallVector<llvm::Value *> materializedWtablePacks;
@@ -692,9 +689,8 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
692
689
auto response = IGF.emitTypeMetadataRef (ty, request);
693
690
auto *metadata = response.getMetadata ();
694
691
for (auto protocol : protocols) {
695
- llvm::Value *_metadata = nullptr ;
696
692
auto *wtable =
697
- emitWitnessTableRef (IGF, ty, /* srcMetadataCache=*/ &_metadata ,
693
+ emitWitnessTableRef (IGF, ty, /* srcMetadataCache=*/ &metadata ,
698
694
ProtocolConformanceRef (protocol));
699
695
wtables.push_back (wtable);
700
696
}
@@ -918,6 +914,71 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
918
914
return metadataPhi;
919
915
}
920
916
917
+ void irgen::bindOpenedElementArchetypesAtIndex (IRGenFunction &IGF,
918
+ GenericEnvironment *environment,
919
+ llvm::Value *index) {
920
+ assert (environment->getKind () == GenericEnvironment::Kind::OpenedElement);
921
+
922
+ // Record the generic type parameters of interest.
923
+ llvm::SmallPtrSet<CanType, 2 > openablePackParams;
924
+ environment->forEachPackElementGenericTypeParam ([&](auto *genericParam) {
925
+ openablePackParams.insert (genericParam->getCanonicalType ());
926
+ });
927
+
928
+ // Find the archetypes and conformances which must be bound.
929
+ llvm::SmallSetVector<CanType, 2 > types;
930
+ llvm::DenseMap<CanType, llvm::SmallVector<ProtocolDecl *, 2 >>
931
+ protocolsForType;
932
+ auto isDerivedFromPackElementGenericTypeParam = [&](CanType ty) -> bool {
933
+ // Is this type itself an openable pack parameter OR a dependent type of
934
+ // one?
935
+ return openablePackParams.contains (
936
+ ty->getRootGenericParam ()->getCanonicalType ());
937
+ };
938
+ enumerateGenericSignatureRequirements (
939
+ environment->getGenericSignature ().getCanonicalSignature (),
940
+ [&](GenericRequirement requirement) {
941
+ switch (requirement.getKind ()) {
942
+ case GenericRequirement::Kind::MetadataPack: {
943
+ auto ty = requirement.getTypeParameter ();
944
+ if (!isDerivedFromPackElementGenericTypeParam (ty))
945
+ return ;
946
+ types.insert (ty);
947
+ protocolsForType.insert ({ty, {}});
948
+ break ;
949
+ }
950
+ case GenericRequirement::Kind::WitnessTablePack: {
951
+ auto ty = requirement.getTypeParameter ();
952
+ if (!isDerivedFromPackElementGenericTypeParam (ty))
953
+ return ;
954
+ types.insert (ty);
955
+ auto iterator = protocolsForType.insert ({ty, {}}).first ;
956
+ iterator->getSecond ().push_back (requirement.getProtocol ());
957
+ break ;
958
+ }
959
+ case GenericRequirement::Kind::Shape:
960
+ case GenericRequirement::Kind::Metadata:
961
+ case GenericRequirement::Kind::WitnessTable:
962
+ break ;
963
+ }
964
+ });
965
+
966
+ // For each archetype to be bound, find the corresponding conformances and
967
+ // bind the metadata and wtables.
968
+ for (auto ty : types) {
969
+ auto protocols = protocolsForType.find (ty)->getSecond ();
970
+ auto archetype = cast<ElementArchetypeType>(
971
+ environment->mapPackTypeIntoElementContext (ty)->getCanonicalType ());
972
+ auto pack =
973
+ cast<PackType>(environment->maybeApplyOuterContextSubstitutions (ty)
974
+ ->getCanonicalType ());
975
+ llvm::SmallVector<llvm::Value *, 2 > wtables;
976
+ auto *metadata = emitTypeMetadataPackElementRef (
977
+ IGF, pack, protocols, index, MetadataState::Complete, wtables);
978
+ IGF.bindArchetype (archetype, metadata, MetadataState::Complete, wtables);
979
+ }
980
+ }
981
+
921
982
void irgen::cleanupTypeMetadataPack (IRGenFunction &IGF,
922
983
StackAddress pack,
923
984
Optional<unsigned > elementCount) {
0 commit comments