@@ -1344,24 +1344,37 @@ static llvm::Optional<TypeLookupError>
1344
1344
checkGenericRequirement (const GenericRequirementDescriptor &req,
1345
1345
llvm::SmallVectorImpl<const void *> &extraArguments,
1346
1346
SubstGenericParameterFn substGenericParam,
1347
- SubstDependentWitnessTableFn substWitnessTable) {
1347
+ SubstDependentWitnessTableFn substWitnessTable,
1348
+ bool allowsUnresolvedSubject) {
1348
1349
assert (!req.getFlags ().isPackRequirement ());
1349
1350
1350
1351
// Make sure we understand the requirement we're dealing with.
1351
1352
if (!req.hasKnownKind ())
1352
1353
return TypeLookupError (" unknown kind" );
1353
1354
1355
+ const Metadata *subjectType = nullptr ;
1356
+
1354
1357
// Resolve the subject generic parameter.
1355
1358
auto result = swift_getTypeByMangledName (
1356
1359
MetadataState::Abstract, req.getParam (), extraArguments.data (),
1357
1360
substGenericParam, substWitnessTable);
1358
- if (result.getError ())
1361
+
1362
+ if (!allowsUnresolvedSubject && result.isError ()) {
1359
1363
return *result.getError ();
1360
- const Metadata *subjectType = result.getType ().getMetadata ();
1364
+ }
1365
+
1366
+ if (!result.isError ()) {
1367
+ subjectType = result.getType ().getMetadata ();
1368
+ }
1361
1369
1362
1370
// Check the requirement.
1363
1371
switch (req.getKind ()) {
1364
1372
case GenericRequirementKind::Protocol: {
1373
+ // Protocol requirements _require_ a subject type.
1374
+ if (result.isError ()) {
1375
+ return *result.getError ();
1376
+ }
1377
+
1365
1378
const WitnessTable *witnessTable = nullptr ;
1366
1379
if (!_conformsToProtocol (nullptr , subjectType, req.getProtocol (),
1367
1380
&witnessTable)) {
@@ -1382,16 +1395,37 @@ checkGenericRequirement(const GenericRequirementDescriptor &req,
1382
1395
}
1383
1396
1384
1397
case GenericRequirementKind::SameType: {
1398
+ // Same type requirements don't require a valid subject.
1399
+
1400
+ const Metadata *sameType = nullptr ;
1401
+
1385
1402
// Demangle the second type under the given substitutions.
1386
1403
auto result = swift_getTypeByMangledName (
1387
1404
MetadataState::Abstract, req.getMangledTypeName (),
1388
1405
extraArguments.data (), substGenericParam, substWitnessTable);
1389
- if (result.getError ())
1406
+
1407
+ if (!allowsUnresolvedSubject && result.isError ()) {
1390
1408
return *result.getError ();
1391
- auto otherType = result.getType ().getMetadata ();
1409
+ }
1410
+
1411
+ if (!result.isError ()) {
1412
+ sameType = result.getType ().getMetadata ();
1413
+ }
1414
+
1415
+ // If we don't have one of either the subject type or the same type and we
1416
+ // have the other, then return this as a success. This assumes the given
1417
+ // extra arguments have provided only the required key arguments in which
1418
+ // case some same type constraints may concretize some generic arguments
1419
+ // making them non-key.
1420
+ //
1421
+ // Note: We don't need to check for allowsUnresolvedSubject here because
1422
+ // these can only be null in the case where we do allow it.
1423
+ if ((!subjectType && sameType) || (subjectType && !sameType)) {
1424
+ return llvm::None;
1425
+ }
1392
1426
1393
1427
// Check that the types are equivalent.
1394
- if (subjectType != otherType ) {
1428
+ if (subjectType != sameType ) {
1395
1429
return TYPE_LOOKUP_ERROR_FMT (
1396
1430
" subject type %.*s does not match %.*s" , (int )req.getParam ().size (),
1397
1431
req.getParam ().data (), (int )req.getMangledTypeName ().size (),
@@ -1402,10 +1436,20 @@ checkGenericRequirement(const GenericRequirementDescriptor &req,
1402
1436
}
1403
1437
1404
1438
case GenericRequirementKind::Layout: {
1439
+ // Layout requirements _require_ a subject type.
1440
+ if (result.isError ()) {
1441
+ return *result.getError ();
1442
+ }
1443
+
1405
1444
return satisfiesLayoutConstraint (req, subjectType);
1406
1445
}
1407
1446
1408
1447
case GenericRequirementKind::BaseClass: {
1448
+ // Base class requirements _require_ a subject type.
1449
+ if (result.isError ()) {
1450
+ return *result.getError ();
1451
+ }
1452
+
1409
1453
// Demangle the base type under the given substitutions.
1410
1454
auto result = swift_getTypeByMangledName (
1411
1455
MetadataState::Abstract, req.getMangledTypeName (),
@@ -1594,7 +1638,8 @@ llvm::Optional<TypeLookupError> swift::_checkGenericRequirements(
1594
1638
llvm::ArrayRef<GenericRequirementDescriptor> requirements,
1595
1639
llvm::SmallVectorImpl<const void *> &extraArguments,
1596
1640
SubstGenericParameterFn substGenericParam,
1597
- SubstDependentWitnessTableFn substWitnessTable) {
1641
+ SubstDependentWitnessTableFn substWitnessTable,
1642
+ bool allowsUnresolvedSubject) {
1598
1643
for (const auto &req : requirements) {
1599
1644
if (req.getFlags ().isPackRequirement ()) {
1600
1645
auto error = checkGenericPackRequirement (req, extraArguments,
@@ -1605,7 +1650,8 @@ llvm::Optional<TypeLookupError> swift::_checkGenericRequirements(
1605
1650
} else {
1606
1651
auto error = checkGenericRequirement (req, extraArguments,
1607
1652
substGenericParam,
1608
- substWitnessTable);
1653
+ substWitnessTable,
1654
+ allowsUnresolvedSubject);
1609
1655
if (error)
1610
1656
return error;
1611
1657
}
0 commit comments