@@ -456,8 +456,6 @@ static llvm::Value *emitPackExpansionElementWitnessTable(
456
456
->mapPackTypeIntoElementContext (patternTy->mapTypeOutOfContext ())
457
457
->getCanonicalType ();
458
458
459
- // FIXME: Handle witness table packs for associatedtype's conformances.
460
-
461
459
// Emit the element witness table.
462
460
auto *wtable = emitWitnessTableRef (IGF, instantiatedPatternTy,
463
461
/* srcMetadataCache=*/ nullptr , conformance);
@@ -567,18 +565,38 @@ void irgen::cleanupWitnessTablePack(IRGenFunction &IGF, StackAddress pack,
567
565
}
568
566
}
569
567
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
+
570
583
llvm::Value *irgen::emitWitnessTablePackRef (IRGenFunction &IGF,
571
584
CanPackType packType,
572
585
PackConformance *conformance) {
573
586
assert (Lowering::TypeConverter::protocolRequiresWitnessTable (
574
587
conformance->getProtocol ()) &&
575
588
" looking up witness table for protocol that doesn't have one" );
576
589
590
+ if (auto *wtable = tryGetLocalPackTypeData (
591
+ IGF, packType,
592
+ LocalTypeDataKind::forAbstractProtocolWitnessTable (
593
+ conformance->getProtocol ())))
594
+ return wtable;
595
+
577
596
auto localDataKind =
578
597
LocalTypeDataKind::forProtocolWitnessTablePack (conformance);
579
598
580
- auto wtable = IGF.tryGetLocalTypeData (packType, localDataKind);
581
- if (wtable)
599
+ if (auto *wtable = tryGetLocalPackTypeData (IGF, packType, localDataKind))
582
600
return wtable;
583
601
584
602
auto pack = emitWitnessTablePack (IGF, packType, conformance);
@@ -600,20 +618,26 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
600
618
tryGetLocalPackTypeMetadata (IGF, packType, request);
601
619
llvm::SmallVector<llvm::Value *> materializedWtablePacks;
602
620
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);
606
625
}
607
626
if (materializedMetadataPack &&
608
627
llvm::all_of (materializedWtablePacks,
609
- [](auto *wtable ) { return wtable ; })) {
628
+ [](auto *wtablePack ) { return wtablePack ; })) {
610
629
auto *gep = IGF.Builder .CreateInBoundsGEP (
611
630
IGF.IGM .TypeMetadataPtrTy , materializedMetadataPack.getMetadata (),
612
631
index);
613
632
auto addr =
614
633
Address (gep, IGF.IGM .TypeMetadataPtrTy , IGF.IGM .getPointerAlignment ());
615
634
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);
617
641
wtables.push_back (wtable);
618
642
}
619
643
return metadata;
0 commit comments