@@ -1154,8 +1154,9 @@ swift_conformsToProtocolMaybeInstantiateSuperclasses(
1154
1154
return {foundWitness, hasUninstantiatedSuperclass};
1155
1155
}
1156
1156
1157
- // / Determine if
1158
- static bool isExecutingInIsolationOfConformance (
1157
+ // / Determine if we are executing within the isolation domain of the global
1158
+ // / actor to which the given conformance is isolated.
1159
+ static bool _isExecutingInIsolationOfConformance (
1159
1160
const Metadata *const type,
1160
1161
const ProtocolConformanceDescriptor *description,
1161
1162
const WitnessTable *table
@@ -1198,6 +1199,164 @@ static bool isExecutingInIsolationOfConformance(
1198
1199
return isCurrentGlobalActor (globalActorType, globalActorWitnessTable);
1199
1200
}
1200
1201
1202
+ static bool _checkConformanceIsolation (
1203
+ const Metadata *const type, const WitnessTable *table);
1204
+
1205
+ // / Check for conformance isolation for a protocol requirement within the
1206
+ // / conditional requirements of a witness table.
1207
+ static bool _checkConformanceIsolationOfProtocolRequirement (
1208
+ const Metadata *const type, const WitnessTable *table,
1209
+ const GenericRequirementDescriptor &requirement,
1210
+ const WitnessTable *conditionalWitnessTable
1211
+ ) {
1212
+ assert (requirement.Flags .getKind () == GenericRequirementKind::Protocol);
1213
+ assert (!requirement.Flags .isPackRequirement ());
1214
+
1215
+ // If the conditional witness table has neither a global actor nor conditional
1216
+ // requirements, there's nothing to check.
1217
+ auto conditionalDescription = conditionalWitnessTable->getDescription ();
1218
+ if (!conditionalDescription ||
1219
+ !(conditionalDescription->hasConditionalRequirements () ||
1220
+ conditionalDescription->hasGlobalActorIsolation ()))
1221
+ return true ;
1222
+
1223
+ // Recurse into this conformance.
1224
+
1225
+ // Resolve the conforming type.
1226
+ SubstGenericParametersFromMetadata substitutions (type);
1227
+ auto result = swift_getTypeByMangledName (
1228
+ MetadataState::Abstract, requirement.getParam (),
1229
+ /* FIXME:conditionalArgs.data()*/ { },
1230
+ [&substitutions](unsigned depth, unsigned index) {
1231
+ return substitutions.getMetadata (depth, index).Ptr ;
1232
+ },
1233
+ [&substitutions](const Metadata *type, unsigned index) {
1234
+ return substitutions.getWitnessTable (type, index);
1235
+ });
1236
+ if (result.isError ())
1237
+ return false ;
1238
+
1239
+ return _checkConformanceIsolation (
1240
+ result.getType ().getMetadata (), conditionalWitnessTable);
1241
+ }
1242
+
1243
+ // / Check for conformance isolation for a protocol requirement pack within the
1244
+ // / conditional requirements of a witness table.
1245
+ static bool _checkConformanceIsolationOfProtocolRequirementPack (
1246
+ const Metadata *const type, const WitnessTable *table,
1247
+ const GenericRequirementDescriptor &requirement,
1248
+ WitnessTablePackPointer conditionalWitnessTables
1249
+ ) {
1250
+ assert (requirement.Flags .getKind () == GenericRequirementKind::Protocol);
1251
+ assert (requirement.Flags .isPackRequirement ());
1252
+
1253
+ // Check each of the conditional witness tables. If any has neither a global
1254
+ // actor nor conditional requirements, there's nothing to check for that one.
1255
+ MetadataPackPointer conformingTypes;
1256
+ unsigned count = conditionalWitnessTables.getNumElements ();
1257
+ for (unsigned index = 0 ; index != count; ++index) {
1258
+ auto conditionalWitnessTable =
1259
+ conditionalWitnessTables.getElements ()[index];
1260
+
1261
+ // If the conditional witness table has neither a global actor nor conditional
1262
+ // requirements, there's nothing to check.
1263
+ auto conditionalDescription = conditionalWitnessTable->getDescription ();
1264
+ if (!conditionalDescription ||
1265
+ !(conditionalDescription->hasConditionalRequirements () ||
1266
+ conditionalDescription->hasGlobalActorIsolation ()))
1267
+ continue ;
1268
+
1269
+ // If we don't have it already, get the parameter pack for the
1270
+ // conforming types.
1271
+ if (!conformingTypes) {
1272
+ // Resolve the conforming type.
1273
+ SubstGenericParametersFromMetadata substitutions (type);
1274
+ auto result = swift::getTypePackByMangledName (
1275
+ requirement.getParam (),
1276
+ /* FIXME:conditionalArgs.data()*/ { },
1277
+ [&substitutions](unsigned depth, unsigned index) {
1278
+ return substitutions.getMetadata (depth, index).Ptr ;
1279
+ },
1280
+ [&substitutions](const Metadata *type, unsigned index) {
1281
+ return substitutions.getWitnessTable (type, index);
1282
+ });
1283
+ if (result.isError ())
1284
+ return false ;
1285
+
1286
+ conformingTypes = result.getType ();
1287
+ assert (conformingTypes.getNumElements () == count);
1288
+ }
1289
+
1290
+ if (!_checkConformanceIsolation (
1291
+ conformingTypes.getElements ()[index], conditionalWitnessTable))
1292
+ return false ;
1293
+ }
1294
+
1295
+ return true ;
1296
+ }
1297
+
1298
+ // / Check whether all isolated conformances in the given witness table (and
1299
+ // / any witness tables it depends on) are satisfied by the current execution
1300
+ // / context.
1301
+ // /
1302
+ // / Returns false if there is an isolated conformance but we are not executing
1303
+ // / in that isolation domain.
1304
+ static bool _checkConformanceIsolation (const Metadata *const type, const WitnessTable *table) {
1305
+ if (!table)
1306
+ return true ;
1307
+
1308
+ auto description = table->getDescription ();
1309
+ if (!description)
1310
+ return true ;
1311
+
1312
+ // If this conformance has global actor isolation, check that we are
1313
+ // running in that isolation domain.
1314
+ if (description->hasGlobalActorIsolation () &&
1315
+ !_isExecutingInIsolationOfConformance (type, description, table)) {
1316
+ return false ;
1317
+ }
1318
+
1319
+ // Check any witness tables that are part of a conditional conformance.
1320
+ unsigned instantiationArgIndex = 0 ;
1321
+ for (const auto &requirement: description->getConditionalRequirements ()) {
1322
+ if (!requirement.Flags .hasKeyArgument ())
1323
+ continue ;
1324
+
1325
+ switch (requirement.Flags .getKind ()) {
1326
+ case GenericRequirementKind::Protocol: {
1327
+ auto instantiationArg =
1328
+ ((void * const *)table)[-1 - (int )instantiationArgIndex];
1329
+ if (requirement.Flags .isPackRequirement ()) {
1330
+ if (!_checkConformanceIsolationOfProtocolRequirementPack (
1331
+ type, table, requirement,
1332
+ WitnessTablePackPointer (instantiationArg)))
1333
+ return false ;
1334
+ } else {
1335
+ if (!_checkConformanceIsolationOfProtocolRequirement (
1336
+ type, table, requirement,
1337
+ (const WitnessTable *)instantiationArg)) {
1338
+ return false ;
1339
+ }
1340
+ }
1341
+
1342
+ break ;
1343
+ }
1344
+
1345
+ case GenericRequirementKind::SameType:
1346
+ case GenericRequirementKind::BaseClass:
1347
+ case GenericRequirementKind::SameConformance:
1348
+ case GenericRequirementKind::SameShape:
1349
+ case GenericRequirementKind::InvertedProtocols:
1350
+ case GenericRequirementKind::Layout:
1351
+ break ;
1352
+ }
1353
+
1354
+ ++instantiationArgIndex;
1355
+ }
1356
+
1357
+ return true ;
1358
+ }
1359
+
1201
1360
static const WitnessTable *
1202
1361
swift_conformsToProtocolCommonImpl (const Metadata *const type,
1203
1362
const ProtocolDescriptor *protocol) {
@@ -1222,17 +1381,9 @@ swift_conformsToProtocolCommonImpl(const Metadata *const type,
1222
1381
swift_conformsToProtocolMaybeInstantiateSuperclasses (
1223
1382
type, protocol, true /* instantiateSuperclassMetadata*/ );
1224
1383
1225
- // If the conformance is isolated to a global actor, check whether we are
1226
- // currently executing on that global actor. Otherwise, the type does not
1227
- // conform.
1228
- if (table) {
1229
- if (auto description = table->getDescription ()) {
1230
- if (description->hasGlobalActorIsolation () &&
1231
- !isExecutingInIsolationOfConformance (type, description, table)) {
1232
- return nullptr ;
1233
- }
1234
- }
1235
- }
1384
+ // Check for isolated conformances.
1385
+ if (!_checkConformanceIsolation (type, table))
1386
+ return nullptr ;
1236
1387
1237
1388
return table;
1238
1389
}
0 commit comments