@@ -262,16 +262,13 @@ static llvm::Value *bindWitnessTableAtIndex(IRGenFunction &IGF,
262262}
263263
264264struct OpenedElementContext {
265- GenericEnvironment *packEnvironment;
266- CanGenericSignature packSignature;
267-
268- GenericEnvironment *elementEnvironment;
269- CanGenericSignature elementSignature;
265+ GenericEnvironment *environment;
266+ CanGenericSignature signature;
270267
271268 static OpenedElementContext
272269 createForPackExpansion (IRGenFunction &IGF, CanPackExpansionType expansionTy) {
273270 // Get the outer generic signature and environment.
274- auto *genericEnv = cast<PackArchetypeType >(expansionTy.getCountType ())
271+ auto *genericEnv = cast<ArchetypeType >(expansionTy.getCountType ())
275272 ->getGenericEnvironment ();
276273 auto subMap = genericEnv->getForwardingSubstitutionMap ();
277274
@@ -282,15 +279,15 @@ struct OpenedElementContext {
282279 auto *elementEnv = GenericEnvironment::forOpenedElement (
283280 elementSig, UUID::fromTime (), expansionTy.getCountType (), subMap);
284281
285- return {genericEnv, genericSig, elementEnv, elementSig};
282+ return {elementEnv, elementSig};
286283 }
287284};
288285
289286static void bindElementSignatureRequirementsAtIndex (
290287 IRGenFunction &IGF, OpenedElementContext const &context, llvm::Value *index,
291288 DynamicMetadataRequest request) {
292289 enumerateGenericSignatureRequirements (
293- context.elementSignature , [&](GenericRequirement requirement) {
290+ context.signature , [&](GenericRequirement requirement) {
294291 switch (requirement.getKind ()) {
295292 case GenericRequirement::Kind::Shape:
296293 case GenericRequirement::Kind::Metadata:
@@ -299,12 +296,12 @@ static void bindElementSignatureRequirementsAtIndex(
299296 case GenericRequirement::Kind::MetadataPack: {
300297 auto ty = requirement.getTypeParameter ();
301298 auto patternPackArchetype = cast<PackArchetypeType>(
302- context.packEnvironment -> mapTypeIntoContext (ty)
299+ context.environment -> maybeApplyOuterContextSubstitutions (ty)
303300 ->getCanonicalType ());
304301 auto response =
305302 IGF.emitTypeMetadataRef (patternPackArchetype, request);
306303 auto elementArchetype =
307- context.elementEnvironment
304+ context.environment
308305 ->mapPackTypeIntoElementContext (
309306 patternPackArchetype->getInterfaceType ())
310307 ->getCanonicalType ();
@@ -319,20 +316,20 @@ static void bindElementSignatureRequirementsAtIndex(
319316 auto ty = requirement.getTypeParameter ();
320317 auto proto = requirement.getProtocol ();
321318 auto patternPackArchetype = cast<PackArchetypeType>(
322- context.packEnvironment -> mapTypeIntoContext (ty)
319+ context.environment -> maybeApplyOuterContextSubstitutions (ty)
323320 ->getCanonicalType ());
324321 auto elementArchetype =
325- context.elementEnvironment
322+ context.environment
326323 ->mapPackTypeIntoElementContext (
327324 patternPackArchetype->getInterfaceType ())
328325 ->getCanonicalType ();
329326 llvm::Value *_metadata = nullptr ;
330327 auto packConformance =
331- context.packSignature ->lookupConformance (ty, proto);
328+ context.signature ->lookupConformance (ty, proto);
332329 auto *wtablePack = emitWitnessTableRef (IGF, patternPackArchetype,
333330 &_metadata, packConformance);
334331 auto elementConformance =
335- context.elementSignature ->lookupConformance (ty, proto);
332+ context.signature ->lookupConformance (ty, proto);
336333 auto *wtable = bindWitnessTableAtIndex (
337334 IGF, elementArchetype, elementConformance, wtablePack, index);
338335 assert (wtable);
@@ -350,7 +347,7 @@ static llvm::Value *emitPackExpansionElementMetadata(
350347
351348 // Replace pack archetypes with element archetypes in the pattern type.
352349 auto instantiatedPatternTy =
353- context.elementEnvironment
350+ context.environment
354351 ->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
355352 ->getCanonicalType ();
356353
@@ -526,11 +523,11 @@ static llvm::Value *emitPackExpansionElementWitnessTable(
526523
527524 // Replace pack archetypes with element archetypes in the pattern type.
528525 auto instantiatedPatternTy =
529- context.elementEnvironment
526+ context.environment
530527 ->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
531528 ->getCanonicalType ();
532529 auto instantiatedConformance =
533- context.elementEnvironment ->getGenericSignature ()->lookupConformance (
530+ context.environment ->getGenericSignature ()->lookupConformance (
534531 instantiatedPatternTy, conformance.getRequirement ());
535532
536533 // Emit the element witness table.
@@ -646,7 +643,7 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
646643 ArrayRef<ProtocolDecl *> protocols, llvm::Value *index,
647644 DynamicMetadataRequest request,
648645 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 .
650647 auto materializedMetadataPack =
651648 tryGetLocalPackTypeMetadata (IGF, packType, request);
652649 llvm::SmallVector<llvm::Value *> materializedWtablePacks;
@@ -692,9 +689,8 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
692689 auto response = IGF.emitTypeMetadataRef (ty, request);
693690 auto *metadata = response.getMetadata ();
694691 for (auto protocol : protocols) {
695- llvm::Value *_metadata = nullptr ;
696692 auto *wtable =
697- emitWitnessTableRef (IGF, ty, /* srcMetadataCache=*/ &_metadata ,
693+ emitWitnessTableRef (IGF, ty, /* srcMetadataCache=*/ &metadata ,
698694 ProtocolConformanceRef (protocol));
699695 wtables.push_back (wtable);
700696 }
@@ -918,6 +914,71 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
918914 return metadataPhi;
919915}
920916
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+
921982void irgen::cleanupTypeMetadataPack (IRGenFunction &IGF,
922983 StackAddress pack,
923984 Optional<unsigned > elementCount) {
0 commit comments