@@ -995,14 +995,9 @@ static bool hasDependentTypeWitness(
995
995
return false ;
996
996
}
997
997
998
- static bool hasDependentTypeWitness (const RootProtocolConformance *root) {
999
- if (auto normal = dyn_cast<NormalProtocolConformance>(root))
1000
- return hasDependentTypeWitness (normal);
1001
- return false ; // no associated types
1002
- }
1003
-
1004
998
static bool isDependentConformance (
1005
999
const RootProtocolConformance *rootConformance,
1000
+ bool considerResilience,
1006
1001
llvm::SmallPtrSet<const NormalProtocolConformance *, 4 > &visited){
1007
1002
// Self-conformances are never dependent.
1008
1003
auto conformance = dyn_cast<NormalProtocolConformance>(rootConformance);
@@ -1015,7 +1010,7 @@ static bool isDependentConformance(
1015
1010
return false ;
1016
1011
1017
1012
// If the conformance is resilient, this is always true.
1018
- if (isResilientConformance (conformance))
1013
+ if (considerResilience && isResilientConformance (conformance))
1019
1014
return true ;
1020
1015
1021
1016
// Check whether any of the conformances are dependent.
@@ -1033,6 +1028,7 @@ static bool isDependentConformance(
1033
1028
if (assocConformance.isAbstract () ||
1034
1029
isDependentConformance (assocConformance.getConcrete ()
1035
1030
->getRootConformance (),
1031
+ considerResilience,
1036
1032
visited))
1037
1033
return true ;
1038
1034
}
@@ -1048,9 +1044,10 @@ static bool isDependentConformance(
1048
1044
1049
1045
// / Is there anything about the given conformance that requires witness
1050
1046
// / tables to be dependently-generated?
1051
- static bool isDependentConformance (const RootProtocolConformance *conformance) {
1047
+ static bool isDependentConformance (const RootProtocolConformance *conformance,
1048
+ bool considerResilience) {
1052
1049
llvm::SmallPtrSet<const NormalProtocolConformance *, 4 > visited;
1053
- return ::isDependentConformance (conformance, visited);
1050
+ return ::isDependentConformance (conformance, considerResilience, visited);
1054
1051
}
1055
1052
1056
1053
static bool isSynthesizedNonUnique (const RootProtocolConformance *conformance) {
@@ -1349,6 +1346,25 @@ class AccessorConformanceInfo : public ConformanceInfo {
1349
1346
return ;
1350
1347
}
1351
1348
1349
+ // If this isn't a conditional conformance, we can emit a mangled name.
1350
+ // FIXME: Conditional conformances won't currently work because the
1351
+ // witness tables for conditional requirements won't have been written
1352
+ // into the private area yet.
1353
+ if (SILConditionalConformances.empty ()) {
1354
+ if (isDependentConformance (astConf->getRootConformance (),
1355
+ /* considerResilience=*/ false ))
1356
+ RequiresSpecialization = true ;
1357
+
1358
+ auto proto = Conformance.getProtocol ();
1359
+ CanType selfType = proto->getProtocolSelfType ()->getCanonicalType ();
1360
+ AssociatedConformance requirement (proto, selfType, baseProto);
1361
+ llvm::Constant *witnessEntry =
1362
+ getAssociatedConformanceWitness (requirement, ConcreteType,
1363
+ ProtocolConformanceRef (astConf));
1364
+ Table.addBitCast (witnessEntry, IGM.Int8PtrTy );
1365
+ return ;
1366
+ }
1367
+
1352
1368
// Otherwise, we'll need to derive it at instantiation time.
1353
1369
RequiresSpecialization = true ;
1354
1370
SpecializedBaseConformances.push_back ({Table.size (), &conf});
@@ -2152,7 +2168,7 @@ IRGenModule::getConformanceInfo(const ProtocolDecl *protocol,
2152
2168
// so in theory we could allocate them on a BumpPtrAllocator. But there's not
2153
2169
// a good one for us to use. (The ASTContext's outlives the IRGenModule in
2154
2170
// batch mode.)
2155
- if (isDependentConformance (rootConformance) ||
2171
+ if (isDependentConformance (rootConformance, /* considerResilience= */ true ) ||
2156
2172
// Foreign types need to go through the accessor to unique the witness
2157
2173
// table.
2158
2174
isSynthesizedNonUnique (rootConformance)) {
@@ -2220,7 +2236,7 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
2220
2236
// Produce the initializer value.
2221
2237
auto initializer = wtableContents.finishAndCreateFuture ();
2222
2238
2223
- bool isDependent = isDependentConformance (conf);
2239
+ bool isDependent = isDependentConformance (conf, /* considerResilience= */ true );
2224
2240
auto global = cast<llvm::GlobalVariable>(
2225
2241
isDependent
2226
2242
? getAddrOfWitnessTablePattern (cast<NormalProtocolConformance>(conf),
@@ -2235,7 +2251,9 @@ void IRGenModule::emitSILWitnessTable(SILWitnessTable *wt) {
2235
2251
wtableBuilder.getTableSize (),
2236
2252
wtableBuilder.getTablePrivateSize (),
2237
2253
wtableBuilder.requiresSpecialization (),
2238
- hasDependentTypeWitness (conf));
2254
+ isDependentConformance (
2255
+ conf,
2256
+ /* considerResilience=*/ false ));
2239
2257
2240
2258
// Build the instantiation function, we if need one.
2241
2259
description.instantiationFn = wtableBuilder.buildInstantiationFunction ();
0 commit comments