@@ -69,6 +69,13 @@ static llvm::Value *tryGetLocalPackTypeData(IRGenFunction &IGF,
69
69
return wtable;
70
70
71
71
if (auto packArchetypeType = getForwardedPackArchetypeType (packType)) {
72
+ // Also unwrap the pack conformance, if there is one.
73
+ if (localDataKind.isPackProtocolConformance ()) {
74
+ localDataKind = LocalTypeDataKind::forProtocolWitnessTable (
75
+ localDataKind.getPackProtocolConformance ()
76
+ ->getPatternConformances ()[0 ]);
77
+ }
78
+
72
79
if (auto *wtable =
73
80
IGF.tryGetLocalTypeData (packArchetypeType, localDataKind))
74
81
return wtable;
@@ -656,17 +663,17 @@ llvm::Value *irgen::emitWitnessTablePackRef(IRGenFunction &IGF,
656
663
657
664
llvm::Value *irgen::emitTypeMetadataPackElementRef (
658
665
IRGenFunction &IGF, CanPackType packType,
659
- ArrayRef<ProtocolDecl *> protocols , llvm::Value *index,
666
+ ArrayRef<ProtocolConformanceRef> conformances , llvm::Value *index,
660
667
DynamicMetadataRequest request,
661
668
llvm::SmallVectorImpl<llvm::Value *> &wtables) {
662
669
// If the packs have already been materialized, just gep into them.
663
670
auto materializedMetadataPack =
664
671
tryGetLocalPackTypeMetadata (IGF, packType, request);
665
672
llvm::SmallVector<llvm::Value *> materializedWtablePacks;
666
- for (auto protocol : protocols ) {
673
+ for (auto conformance : conformances ) {
667
674
auto *wtablePack = tryGetLocalPackTypeData (
668
675
IGF, packType,
669
- LocalTypeDataKind::forAbstractProtocolWitnessTable (protocol ));
676
+ LocalTypeDataKind::forProtocolWitnessTable (conformance ));
670
677
materializedWtablePacks.push_back (wtablePack);
671
678
}
672
679
if (materializedMetadataPack &&
@@ -696,10 +703,12 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
696
703
auto ty = packType.getElementType (index);
697
704
auto response = IGF.emitTypeMetadataRef (ty, request);
698
705
auto *metadata = response.getMetadata ();
699
- for (auto protocol : protocols) {
706
+ for (auto conformance : conformances) {
707
+ auto patternConformance = conformance.getPack ()
708
+ ->getPatternConformances ()[index];
700
709
auto *wtable =
701
710
emitWitnessTableRef (IGF, ty, /* srcMetadataCache=*/ &metadata,
702
- ProtocolConformanceRef (protocol) );
711
+ patternConformance );
703
712
wtables.push_back (wtable);
704
713
}
705
714
return metadata;
@@ -801,8 +810,8 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
801
810
auto *metadataPhi = IGF.Builder .CreatePHI (IGF.IGM .TypeMetadataPtrTy ,
802
811
packType.getElementTypes ().size ());
803
812
llvm::SmallVector<llvm::PHINode *, 2 > wtablePhis;
804
- wtablePhis.reserve (protocols .size ());
805
- for (auto idx : indices (protocols )) {
813
+ wtablePhis.reserve (conformances .size ());
814
+ for (auto idx : indices (conformances )) {
806
815
(void )idx;
807
816
wtablePhis.push_back (IGF.Builder .CreatePHI (
808
817
IGF.IGM .WitnessTablePtrTy , packType.getElementTypes ().size ()));
@@ -818,7 +827,9 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
818
827
llvm::BasicBlock *previousInBounds = nullptr ;
819
828
// The lower bound of indices for the current pack expansion. Inclusive.
820
829
llvm::Value *lowerBound = llvm::ConstantInt::get (IGF.IGM .SizeTy , 0 );
821
- for (auto elementTy : packType.getElementTypes ()) {
830
+ for (unsigned i = 0 , e = packType->getNumElements (); i < e; ++i) {
831
+ auto elementTy = packType.getElementType (i);
832
+
822
833
// The block within which it will be checked whether %index corresponds to
823
834
// an element of the pack expansion elementTy.
824
835
auto *checkBounds = IGF.createBasicBlock (" pack-index-element-bounds" );
@@ -866,7 +877,7 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
866
877
867
878
llvm::Value *metadata = nullptr ;
868
879
llvm::SmallVector<llvm::Value *, 2 > wtables;
869
- wtables.reserve (protocols .size ());
880
+ wtables.reserve (conformances .size ());
870
881
if (auto expansionTy = dyn_cast<PackExpansionType>(elementTy)) {
871
882
// Actually materialize %inner. Then use it to get the metadata from the
872
883
// pack expansion at that index.
@@ -876,19 +887,21 @@ llvm::Value *irgen::emitTypeMetadataPackElementRef(
876
887
auto patternTy = expansionTy.getPatternType ();
877
888
metadata = emitPackExpansionElementMetadata (IGF, context, patternTy,
878
889
relativeIndex, request);
879
- for (auto protocol : protocols) {
890
+ for (auto conformance : conformances) {
891
+ auto patternConformance = conformance.getPack ()->getPatternConformances ()[i];
880
892
auto *wtable = emitPackExpansionElementWitnessTable (
881
- IGF, context, patternTy, ProtocolConformanceRef (protocol) ,
893
+ IGF, context, patternTy, patternConformance ,
882
894
&metadata, relativeIndex);
883
895
wtables.push_back (wtable);
884
896
}
885
897
} else {
886
898
metadata = IGF.emitTypeMetadataRef (elementTy, request).getMetadata ();
887
- for (auto protocol : protocols) {
899
+ for (auto conformance : conformances) {
900
+ auto patternConformance = conformance.getPack ()->getPatternConformances ()[i];
888
901
llvm::Value *_metadata = nullptr ;
889
902
auto *wtable =
890
903
emitWitnessTableRef (IGF, elementTy, /* srcMetadataCache=*/ &_metadata,
891
- ProtocolConformanceRef (protocol) );
904
+ patternConformance );
892
905
wtables.push_back (wtable);
893
906
}
894
907
}
@@ -935,10 +948,12 @@ void irgen::bindOpenedElementArchetypesAtIndex(IRGenFunction &IGF,
935
948
openablePackParams.insert (genericParam->getCanonicalType ());
936
949
});
937
950
951
+ auto subs = environment->getPackElementContextSubstitutions ();
952
+
938
953
// Find the archetypes and conformances which must be bound.
939
954
llvm::SmallSetVector<CanType, 2 > types;
940
- llvm::DenseMap<CanType, llvm::SmallVector<ProtocolDecl * , 2 >>
941
- protocolsForType ;
955
+ llvm::DenseMap<CanType, llvm::SmallVector<ProtocolConformanceRef , 2 >>
956
+ conformancesForType ;
942
957
auto isDerivedFromPackElementGenericTypeParam = [&](CanType ty) -> bool {
943
958
// Is this type itself an openable pack parameter OR a dependent type of
944
959
// one?
@@ -954,16 +969,19 @@ void irgen::bindOpenedElementArchetypesAtIndex(IRGenFunction &IGF,
954
969
if (!isDerivedFromPackElementGenericTypeParam (ty))
955
970
return ;
956
971
types.insert (ty);
957
- protocolsForType .insert ({ty, {}});
972
+ conformancesForType .insert ({ty, {}});
958
973
break ;
959
974
}
960
975
case GenericRequirement::Kind::WitnessTablePack: {
961
976
auto ty = requirement.getTypeParameter ();
962
977
if (!isDerivedFromPackElementGenericTypeParam (ty))
963
978
return ;
964
979
types.insert (ty);
965
- auto iterator = protocolsForType.insert ({ty, {}}).first ;
966
- iterator->getSecond ().push_back (requirement.getProtocol ());
980
+ auto iterator = conformancesForType.insert ({ty, {}}).first ;
981
+
982
+ auto conformance = subs.lookupConformance (
983
+ ty, requirement.getProtocol ());
984
+ iterator->getSecond ().push_back (conformance);
967
985
break ;
968
986
}
969
987
case GenericRequirement::Kind::Shape:
@@ -976,15 +994,14 @@ void irgen::bindOpenedElementArchetypesAtIndex(IRGenFunction &IGF,
976
994
// For each archetype to be bound, find the corresponding conformances and
977
995
// bind the metadata and wtables.
978
996
for (auto ty : types) {
979
- auto protocols = protocolsForType .find (ty)->getSecond ();
997
+ auto conformances = conformancesForType .find (ty)->getSecond ();
980
998
auto archetype = cast<ElementArchetypeType>(
981
999
environment->mapPackTypeIntoElementContext (ty)->getCanonicalType ());
982
- auto pack =
983
- cast<PackType>(environment->maybeApplyOuterContextSubstitutions (ty)
984
- ->getCanonicalType ());
1000
+ auto packType = cast<PackType>(ty.subst (subs)->getCanonicalType ());
1001
+
985
1002
llvm::SmallVector<llvm::Value *, 2 > wtables;
986
1003
auto *metadata = emitTypeMetadataPackElementRef (
987
- IGF, pack, protocols , index, MetadataState::Complete, wtables);
1004
+ IGF, packType, conformances , index, MetadataState::Complete, wtables);
988
1005
IGF.bindArchetype (archetype, metadata, MetadataState::Complete, wtables);
989
1006
}
990
1007
}
0 commit comments