@@ -456,8 +456,6 @@ static llvm::Value *emitPackExpansionElementWitnessTable(
456456 ->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
457457 ->getCanonicalType ();
458458
459- // FIXME: Handle witness table packs for associatedtype's conformances.
460-
461459 // Emit the element witness table.
462460 auto *wtable = emitWitnessTableRef (IGF, instantiatedPatternTy,
463461 /* srcMetadataCache=*/ nullptr , conformance);
@@ -567,18 +565,38 @@ void irgen::cleanupWitnessTablePack(IRGenFunction &IGF, StackAddress pack,
567565 }
568566}
569567
568+ static llvm::Value *tryGetLocalPackTypeData (IRGenFunction &IGF,
569+ CanPackType packType,
570+ LocalTypeDataKind localDataKind) {
571+ if (auto *wtable = IGF.tryGetLocalTypeData (packType, localDataKind))
572+ return wtable;
573+
574+ if (auto packArchetypeType = getForwardedPackArchetypeType (packType)) {
575+ if (auto *wtable =
576+ IGF.tryGetLocalTypeData (packArchetypeType, localDataKind))
577+ return wtable;
578+ }
579+
580+ return nullptr ;
581+ }
582+
570583llvm::Value *irgen::emitWitnessTablePackRef (IRGenFunction &IGF,
571584 CanPackType packType,
572585 PackConformance *conformance) {
573586 assert (Lowering::TypeConverter::protocolRequiresWitnessTable (
574587 conformance->getProtocol ()) &&
575588 " looking up witness table for protocol that doesn't have one" );
576589
590+ if (auto *wtable = tryGetLocalPackTypeData (
591+ IGF, packType,
592+ LocalTypeDataKind::forAbstractProtocolWitnessTable (
593+ conformance->getProtocol ())))
594+ return wtable;
595+
577596 auto localDataKind =
578597 LocalTypeDataKind::forProtocolWitnessTablePack (conformance);
579598
580- auto wtable = IGF.tryGetLocalTypeData (packType, localDataKind);
581- if (wtable)
599+ if (auto *wtable = tryGetLocalPackTypeData (IGF, packType, localDataKind))
582600 return wtable;
583601
584602 auto pack = emitWitnessTablePack (IGF, packType, conformance);
@@ -600,20 +618,26 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
600618 tryGetLocalPackTypeMetadata (IGF, packType, request);
601619 llvm::SmallVector<llvm::Value *> materializedWtablePacks;
602620 for (auto protocol : protocols) {
603- auto wtable = IGF.tryGetLocalTypeData (
604- packType, LocalTypeDataKind::forAbstractProtocolWitnessTable (protocol));
605- materializedWtablePacks.push_back (wtable);
621+ auto *wtablePack = tryGetLocalPackTypeData (
622+ IGF, packType,
623+ LocalTypeDataKind::forAbstractProtocolWitnessTable (protocol));
624+ materializedWtablePacks.push_back (wtablePack);
606625 }
607626 if (materializedMetadataPack &&
608627 llvm::all_of (materializedWtablePacks,
609- [](auto *wtable ) { return wtable ; })) {
628+ [](auto *wtablePack ) { return wtablePack ; })) {
610629 auto *gep = IGF.Builder .CreateInBoundsGEP (
611630 IGF.IGM .TypeMetadataPtrTy , materializedMetadataPack.getMetadata (),
612631 index);
613632 auto addr =
614633 Address (gep, IGF.IGM .TypeMetadataPtrTy , IGF.IGM .getPointerAlignment ());
615634 auto *metadata = IGF.Builder .CreateLoad (addr);
616- for (auto *wtable : materializedWtablePacks) {
635+ for (auto *wtablePack : materializedWtablePacks) {
636+ auto *gep = IGF.Builder .CreateInBoundsGEP (IGF.IGM .WitnessTablePtrTy ,
637+ wtablePack, index);
638+ auto addr = Address (gep, IGF.IGM .WitnessTablePtrTy ,
639+ IGF.IGM .getPointerAlignment ());
640+ auto *wtable = IGF.Builder .CreateLoad (addr);
617641 wtables.push_back (wtable);
618642 }
619643 return metadata;
0 commit comments