@@ -1281,122 +1281,135 @@ bool swift::_swift_class_isSubclass(const Metadata *subclass,
1281
1281
return isSubclass (subclass, superclass);
1282
1282
}
1283
1283
1284
- llvm::Optional<TypeLookupError> swift::_checkGenericRequirements (
1285
- llvm::ArrayRef<GenericRequirementDescriptor> requirements,
1286
- llvm::SmallVectorImpl<const void *> &extraArguments,
1287
- SubstGenericParameterFn substGenericParam,
1288
- SubstDependentWitnessTableFn substWitnessTable) {
1289
- for (const auto &req : requirements) {
1290
- // Make sure we understand the requirement we're dealing with.
1291
- if (!req.hasKnownKind ())
1292
- return TypeLookupError (" unknown kind" );
1284
+ static llvm::Optional<TypeLookupError>
1285
+ checkGenericRequirement (const GenericRequirementDescriptor &req,
1286
+ llvm::SmallVectorImpl<const void *> &extraArguments,
1287
+ SubstGenericParameterFn substGenericParam,
1288
+ SubstDependentWitnessTableFn substWitnessTable) {
1289
+ assert (!req.getFlags ().isPackRequirement ());
1290
+
1291
+ // Make sure we understand the requirement we're dealing with.
1292
+ if (!req.hasKnownKind ())
1293
+ return TypeLookupError (" unknown kind" );
1294
+
1295
+ // Resolve the subject generic parameter.
1296
+ auto result = swift_getTypeByMangledName (
1297
+ MetadataState::Abstract, req.getParam (), extraArguments.data (),
1298
+ substGenericParam, substWitnessTable);
1299
+ if (result.getError ())
1300
+ return *result.getError ();
1301
+ const Metadata *subjectType = result.getType ().getMetadata ();
1302
+
1303
+ // Check the requirement.
1304
+ switch (req.getKind ()) {
1305
+ case GenericRequirementKind::Protocol: {
1306
+ const WitnessTable *witnessTable = nullptr ;
1307
+ if (!_conformsToProtocol (nullptr , subjectType, req.getProtocol (),
1308
+ &witnessTable)) {
1309
+ const char *protoName =
1310
+ req.getProtocol () ? req.getProtocol ().getName () : " <null>" ;
1311
+ return TYPE_LOOKUP_ERROR_FMT (
1312
+ " subject type %.*s does not conform to protocol %s" ,
1313
+ (int )req.getParam ().size (), req.getParam ().data (), protoName);
1314
+ }
1293
1315
1294
- if (req.getFlags ().isPackRequirement ())
1295
- return TypeLookupError (" Packs not supported here yet" );
1316
+ // If we need a witness table, add it.
1317
+ if (req.getProtocol ().needsWitnessTable ()) {
1318
+ assert (witnessTable);
1319
+ extraArguments.push_back (witnessTable);
1320
+ }
1296
1321
1297
- // Resolve the subject generic parameter.
1322
+ return llvm::None;
1323
+ }
1324
+
1325
+ case GenericRequirementKind::SameType: {
1326
+ // Demangle the second type under the given substitutions.
1298
1327
auto result = swift_getTypeByMangledName (
1299
- MetadataState::Abstract, req.getParam (), extraArguments. data (),
1300
- substGenericParam, substWitnessTable);
1328
+ MetadataState::Abstract, req.getMangledTypeName (),
1329
+ extraArguments. data (), substGenericParam, substWitnessTable);
1301
1330
if (result.getError ())
1302
1331
return *result.getError ();
1303
- const Metadata *subjectType = result.getType ().getMetadata ();
1304
-
1305
- // Check the requirement.
1306
- switch (req.getKind ()) {
1307
- case GenericRequirementKind::Protocol: {
1308
- const WitnessTable *witnessTable = nullptr ;
1309
- if (!_conformsToProtocol (nullptr , subjectType, req.getProtocol (),
1310
- &witnessTable)) {
1311
- const char *protoName =
1312
- req.getProtocol () ? req.getProtocol ().getName () : " <null>" ;
1313
- return TYPE_LOOKUP_ERROR_FMT (
1314
- " subject type %.*s does not conform to protocol %s" ,
1315
- (int )req.getParam ().size (), req.getParam ().data (), protoName);
1316
- }
1317
-
1318
- // If we need a witness table, add it.
1319
- if (req.getProtocol ().needsWitnessTable ()) {
1320
- assert (witnessTable);
1321
- extraArguments.push_back (witnessTable);
1322
- }
1323
-
1324
- continue ;
1332
+ auto otherType = result.getType ().getMetadata ();
1333
+
1334
+ // Check that the types are equivalent.
1335
+ if (subjectType != otherType) {
1336
+ return TYPE_LOOKUP_ERROR_FMT (
1337
+ " subject type %.*s does not match %.*s" , (int )req.getParam ().size (),
1338
+ req.getParam ().data (), (int )req.getMangledTypeName ().size (),
1339
+ req.getMangledTypeName ().data ());
1325
1340
}
1326
1341
1327
- case GenericRequirementKind::SameType: {
1328
- // Demangle the second type under the given substitutions.
1329
- auto result = swift_getTypeByMangledName (
1330
- MetadataState::Abstract, req.getMangledTypeName (),
1331
- extraArguments.data (), substGenericParam, substWitnessTable);
1332
- if (result.getError ())
1333
- return *result.getError ();
1334
- auto otherType = result.getType ().getMetadata ();
1335
-
1336
- // Check that the types are equivalent.
1337
- if (subjectType != otherType)
1338
- return TYPE_LOOKUP_ERROR_FMT (
1339
- " subject type %.*s does not match %.*s" , (int )req.getParam ().size (),
1340
- req.getParam ().data (), (int )req.getMangledTypeName ().size (),
1341
- req.getMangledTypeName ().data ());
1342
+ return llvm::None;
1343
+ }
1342
1344
1343
- continue ;
1345
+ case GenericRequirementKind::Layout: {
1346
+ switch (req.getLayout ()) {
1347
+ case GenericRequirementLayoutKind::Class:
1348
+ if (!subjectType->satisfiesClassConstraint ()) {
1349
+ return TYPE_LOOKUP_ERROR_FMT (
1350
+ " subject type %.*s does not satisfy class constraint" ,
1351
+ (int )req.getParam ().size (), req.getParam ().data ());
1352
+ }
1353
+ return llvm::None;
1344
1354
}
1345
1355
1346
- case GenericRequirementKind::Layout: {
1347
- switch (req.getLayout ()) {
1348
- case GenericRequirementLayoutKind::Class:
1349
- if (!subjectType->satisfiesClassConstraint ())
1350
- return TYPE_LOOKUP_ERROR_FMT (
1351
- " subject type %.*s does not satisfy class constraint" ,
1352
- (int )req.getParam ().size (), req.getParam ().data ());
1353
- continue ;
1354
- }
1356
+ // Unknown layout.
1357
+ return TYPE_LOOKUP_ERROR_FMT (" unknown layout kind %u" , req.getLayout ());
1358
+ }
1355
1359
1356
- // Unknown layout.
1357
- return TYPE_LOOKUP_ERROR_FMT (" unknown layout kind %u" , req.getLayout ());
1360
+ case GenericRequirementKind::BaseClass: {
1361
+ // Demangle the base type under the given substitutions.
1362
+ auto result = swift_getTypeByMangledName (
1363
+ MetadataState::Abstract, req.getMangledTypeName (),
1364
+ extraArguments.data (), substGenericParam, substWitnessTable);
1365
+ if (result.getError ())
1366
+ return *result.getError ();
1367
+ auto baseType = result.getType ().getMetadata ();
1368
+
1369
+ // If the type which is constrained to a base class is an existential
1370
+ // type, and if that existential type includes a superclass constraint,
1371
+ // just require that the superclass by which the existential is
1372
+ // constrained is a subclass of the base class.
1373
+ if (auto *existential = dyn_cast<ExistentialTypeMetadata>(subjectType)) {
1374
+ if (auto *superclassConstraint = existential->getSuperclassConstraint ())
1375
+ subjectType = superclassConstraint;
1358
1376
}
1359
1377
1360
- case GenericRequirementKind::BaseClass: {
1361
- // Demangle the base type under the given substitutions.
1362
- auto result = swift_getTypeByMangledName (
1363
- MetadataState::Abstract, req.getMangledTypeName (),
1364
- extraArguments.data (), substGenericParam, substWitnessTable);
1365
- if (result.getError ())
1366
- return *result.getError ();
1367
- auto baseType = result.getType ().getMetadata ();
1368
-
1369
- // If the type which is constrained to a base class is an existential
1370
- // type, and if that existential type includes a superclass constraint,
1371
- // just require that the superclass by which the existential is
1372
- // constrained is a subclass of the base class.
1373
- if (auto *existential = dyn_cast<ExistentialTypeMetadata>(subjectType)) {
1374
- if (auto *superclassConstraint = existential->getSuperclassConstraint ())
1375
- subjectType = superclassConstraint;
1376
- }
1378
+ if (!isSubclass (subjectType, baseType))
1379
+ return TYPE_LOOKUP_ERROR_FMT (
1380
+ " %.*s is not subclass of %.*s" , (int )req.getParam ().size (),
1381
+ req.getParam ().data (), (int )req.getMangledTypeName ().size (),
1382
+ req.getMangledTypeName ().data ());
1377
1383
1378
- if (!isSubclass (subjectType, baseType))
1379
- return TYPE_LOOKUP_ERROR_FMT (
1380
- " %.*s is not subclass of %.*s" , (int )req.getParam ().size (),
1381
- req.getParam ().data (), (int )req.getMangledTypeName ().size (),
1382
- req.getMangledTypeName ().data ());
1384
+ return llvm::None;
1385
+ }
1383
1386
1384
- continue ;
1385
- }
1387
+ case GenericRequirementKind::SameConformance: {
1388
+ // FIXME: Implement this check.
1389
+ return llvm::None;
1390
+ }
1386
1391
1387
- case GenericRequirementKind::SameConformance: {
1388
- // FIXME: Implement this check.
1389
- continue ;
1390
- }
1392
+ case GenericRequirementKind::SameShape: {
1393
+ return TYPE_LOOKUP_ERROR_FMT (" can't have same-shape requirement where "
1394
+ " subject type is not a pack" );
1395
+ }
1396
+ }
1391
1397
1392
- case GenericRequirementKind::SameShape: {
1393
- llvm_unreachable ( " Implement me " );
1394
- }
1395
- }
1398
+ // Unknown generic requirement kind.
1399
+ return TYPE_LOOKUP_ERROR_FMT ( " unknown generic requirement kind %u " ,
1400
+ ( unsigned )req. getKind ());
1401
+ }
1396
1402
1397
- // Unknown generic requirement kind.
1398
- return TYPE_LOOKUP_ERROR_FMT (" unknown generic requirement kind %u" ,
1399
- (unsigned )req.getKind ());
1403
+ llvm::Optional<TypeLookupError> swift::_checkGenericRequirements (
1404
+ llvm::ArrayRef<GenericRequirementDescriptor> requirements,
1405
+ llvm::SmallVectorImpl<const void *> &extraArguments,
1406
+ SubstGenericParameterFn substGenericParam,
1407
+ SubstDependentWitnessTableFn substWitnessTable) {
1408
+ for (const auto &req : requirements) {
1409
+ auto error = checkGenericRequirement (req, extraArguments,
1410
+ substGenericParam, substWitnessTable);
1411
+ if (error)
1412
+ return error;
1400
1413
}
1401
1414
1402
1415
// Success!
0 commit comments