Skip to content

Commit d776f71

Browse files
committed
Runtime: Teach checkGenericRequirements() to check same-shape and conformance pack requirements
1 parent 2cf1241 commit d776f71

File tree

8 files changed

+167
-44
lines changed

8 files changed

+167
-44
lines changed

stdlib/public/runtime/Demangle.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -420,7 +420,8 @@ static bool _buildDemanglingForGenericArgs(
420420
req.getMangledTypeName(),
421421
reinterpret_cast<const void * const *>(genericArgs),
422422
[&substitutions](unsigned depth, unsigned index) {
423-
return substitutions.getMetadata(depth, index);
423+
// FIXME: Variadic generics
424+
return substitutions.getMetadata(depth, index).getMetadata();
424425
},
425426
[&substitutions](const Metadata *type, unsigned index) {
426427
return substitutions.getWitnessTable(type, index);

stdlib/public/runtime/DynamicCast.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1865,7 +1865,8 @@ static DynamicCastResult tryCastToExtendedExistential(
18651865
destExistentialShape->getRequirementSignature().getRequirements(),
18661866
allGenericArgsVec,
18671867
[&substitutions](unsigned depth, unsigned index) {
1868-
return substitutions.getMetadata(depth, index);
1868+
// FIXME: Variadic generics
1869+
return substitutions.getMetadata(depth, index).getMetadata();
18691870
},
18701871
[](const Metadata *type, unsigned index) -> const WitnessTable * {
18711872
swift_unreachable("Resolution of witness tables is not supported");

stdlib/public/runtime/Metadata.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3388,7 +3388,8 @@ getSuperclassMetadata(MetadataRequest request, const ClassMetadata *self) {
33883388
auto result = swift_getTypeByMangledName(
33893389
request, superclassName, substitutions.getGenericArgs(),
33903390
[&substitutions](unsigned depth, unsigned index) {
3391-
return substitutions.getMetadata(depth, index);
3391+
// FIXME: Variadic generics
3392+
return substitutions.getMetadata(depth, index).getMetadata();
33923393
},
33933394
[&substitutions](const Metadata *type, unsigned index) {
33943395
return substitutions.getWitnessTable(type, index);
@@ -6102,7 +6103,8 @@ swift_getAssociatedTypeWitnessSlowImpl(
61026103
result = swift_getTypeByMangledName(
61036104
request, mangledName, substitutions.getGenericArgs(),
61046105
[&substitutions](unsigned depth, unsigned index) {
6105-
return substitutions.getMetadata(depth, index);
6106+
// FIXME: Variadic generics
6107+
return substitutions.getMetadata(depth, index).getMetadata();
61066108
},
61076109
[&substitutions](const Metadata *type, unsigned index) {
61086110
return substitutions.getWitnessTable(type, index);

stdlib/public/runtime/MetadataLookup.cpp

Lines changed: 30 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1139,7 +1139,7 @@ class SubstGenericParametersFromWrittenArgs {
11391139
: allGenericArgs(allGenericArgs),
11401140
genericParamCounts(genericParamCounts) {}
11411141

1142-
const Metadata *getMetadata(unsigned depth, unsigned index) const;
1142+
MetadataOrPack getMetadata(unsigned depth, unsigned index) const;
11431143
const WitnessTable *getWitnessTable(const Metadata *type,
11441144
unsigned index) const;
11451145
};
@@ -1332,7 +1332,7 @@ _gatherGenericParameters(const ContextDescriptor *context,
13321332
auto error = _checkGenericRequirements(
13331333
generics->getGenericRequirements(), allGenericArgsVec,
13341334
[&substitutions](unsigned depth, unsigned index) {
1335-
return substitutions.getMetadata(depth, index);
1335+
return substitutions.getMetadata(depth, index).Ptr;
13361336
},
13371337
[&substitutions](const Metadata *type, unsigned index) {
13381338
return substitutions.getWitnessTable(type, index);
@@ -1577,7 +1577,8 @@ class DecodedMetadataBuilder {
15771577
swift_getTypeByMangledName(MetadataState::Complete,
15781578
mangledName, allGenericArgsVec.data(),
15791579
[&substitutions](unsigned depth, unsigned index) {
1580-
return substitutions.getMetadata(depth, index);
1580+
// FIXME: Variadic generics
1581+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
15811582
},
15821583
[&substitutions](const Metadata *type, unsigned index) {
15831584
return substitutions.getWitnessTable(type, index);
@@ -2172,7 +2173,8 @@ swift_getTypeByMangledNameInEnvironment(
21722173
MetadataState::Complete, typeName,
21732174
genericArgs,
21742175
[&substitutions](unsigned depth, unsigned index) {
2175-
return substitutions.getMetadata(depth, index);
2176+
// FIXME: Variadic generics
2177+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
21762178
},
21772179
[&substitutions](const Metadata *type, unsigned index) {
21782180
return substitutions.getWitnessTable(type, index);
@@ -2204,7 +2206,8 @@ swift_getTypeByMangledNameInEnvironmentInMetadataState(
22042206
(MetadataState)metadataState, typeName,
22052207
genericArgs,
22062208
[&substitutions](unsigned depth, unsigned index) {
2207-
return substitutions.getMetadata(depth, index);
2209+
// FIXME: Variadic generics
2210+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
22082211
},
22092212
[&substitutions](const Metadata *type, unsigned index) {
22102213
return substitutions.getWitnessTable(type, index);
@@ -2235,7 +2238,8 @@ swift_getTypeByMangledNameInContext(
22352238
MetadataState::Complete, typeName,
22362239
genericArgs,
22372240
[&substitutions](unsigned depth, unsigned index) {
2238-
return substitutions.getMetadata(depth, index);
2241+
// FIXME: Variadic generics
2242+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
22392243
},
22402244
[&substitutions](const Metadata *type, unsigned index) {
22412245
return substitutions.getWitnessTable(type, index);
@@ -2267,7 +2271,8 @@ swift_getTypeByMangledNameInContextInMetadataState(
22672271
(MetadataState)metadataState, typeName,
22682272
genericArgs,
22692273
[&substitutions](unsigned depth, unsigned index) {
2270-
return substitutions.getMetadata(depth, index);
2274+
// FIXME: Variadic generics
2275+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
22712276
},
22722277
[&substitutions](const Metadata *type, unsigned index) {
22732278
return substitutions.getWitnessTable(type, index);
@@ -2453,7 +2458,8 @@ swift_func_getReturnTypeInfo(const char *typeNameStart, size_t typeNameLength,
24532458
demangler,
24542459
/*substGenericParam=*/
24552460
[&substFn](unsigned depth, unsigned index) {
2456-
return substFn.getMetadata(depth, index);
2461+
// FIXME: Variadic generics
2462+
return substFn.getMetadata(depth, index).getMetadataOrNull();
24572463
},
24582464
/*SubstDependentWitnessTableFn=*/
24592465
[&substFn](const Metadata *type, unsigned index) {
@@ -2494,7 +2500,8 @@ swift_func_getParameterTypeInfo(
24942500
demangler,
24952501
/*substGenericParam=*/
24962502
[&substFn](unsigned depth, unsigned index) {
2497-
return substFn.getMetadata(depth, index);
2503+
// FIXME: Variadic generics
2504+
return substFn.getMetadata(depth, index).getMetadataOrNull();
24982505
},
24992506
/*SubstDependentWitnessTableFn=*/
25002507
[&substFn](const Metadata *type, unsigned index) {
@@ -2537,7 +2544,8 @@ swift_distributed_getWitnessTables(GenericEnvironmentDescriptor *genericEnv,
25372544
auto error = _checkGenericRequirements(
25382545
genericEnv->getGenericRequirements(), witnessTables,
25392546
[&substFn](unsigned depth, unsigned index) {
2540-
return substFn.getMetadata(depth, index);
2547+
// FIXME: Variadic generics
2548+
return substFn.getMetadata(depth, index).getMetadataOrNull();
25412549
},
25422550
[&substFn](const Metadata *type, unsigned index) {
25432551
return substFn.getWitnessTable(type, index);
@@ -2571,7 +2579,8 @@ swift_getOpaqueTypeMetadata(MetadataRequest request,
25712579
return swift_getTypeByMangledName(request.getState(),
25722580
mangledName, arguments,
25732581
[&substitutions](unsigned depth, unsigned index) {
2574-
return substitutions.getMetadata(depth, index);
2582+
// FIXME: Variadic generics
2583+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
25752584
},
25762585
[&substitutions](const Metadata *type, unsigned index) {
25772586
return substitutions.getWitnessTable(type, index);
@@ -2823,22 +2832,22 @@ void SubstGenericParametersFromMetadata::setup() const {
28232832
}
28242833
}
28252834

2826-
const Metadata *
2835+
MetadataOrPack
28272836
SubstGenericParametersFromMetadata::getMetadata(
28282837
unsigned depth, unsigned index) const {
28292838
// On first access, compute the descriptor path.
28302839
setup();
28312840

28322841
// If the depth is too great, there is nothing to do.
28332842
if (depth >= descriptorPath.size())
2834-
return nullptr;
2843+
return MetadataOrPack();
28352844

28362845
/// Retrieve the descriptor path element at this depth.
28372846
auto &pathElement = descriptorPath[depth];
28382847

28392848
// Check whether the index is clearly out of bounds.
28402849
if (index >= pathElement.numTotalGenericParams)
2841-
return nullptr;
2850+
return MetadataOrPack();
28422851

28432852
// Compute the flat index.
28442853
unsigned flatIndex = pathElement.numKeyGenericParamsInParent;
@@ -2849,7 +2858,7 @@ SubstGenericParametersFromMetadata::getMetadata(
28492858

28502859
// Make sure that the requested parameter itself has a key argument.
28512860
if (!genericParams[index].hasKeyArgument())
2852-
return nullptr;
2861+
return MetadataOrPack();
28532862

28542863
// Increase the flat index for each parameter with a key argument, up to
28552864
// the given index.
@@ -2861,7 +2870,7 @@ SubstGenericParametersFromMetadata::getMetadata(
28612870
flatIndex += index;
28622871
}
28632872

2864-
return (const Metadata *)genericArgs[flatIndex];
2873+
return MetadataOrPack(genericArgs[flatIndex]);
28652874
}
28662875

28672876
const WitnessTable *
@@ -2873,17 +2882,16 @@ SubstGenericParametersFromMetadata::getWitnessTable(const Metadata *type,
28732882
return (const WitnessTable *)genericArgs[index + numKeyGenericParameters];
28742883
}
28752884

2876-
const Metadata *SubstGenericParametersFromWrittenArgs::getMetadata(
2885+
MetadataOrPack SubstGenericParametersFromWrittenArgs::getMetadata(
28772886
unsigned depth, unsigned index) const {
28782887
if (auto flatIndex =
28792888
_depthIndexToFlatIndex(depth, index, genericParamCounts)) {
28802889
if (*flatIndex < allGenericArgs.size()) {
2881-
// FIXME: variadic generics
2882-
return allGenericArgs[*flatIndex].getMetadata();
2890+
return MetadataOrPack(allGenericArgs[*flatIndex]);
28832891
}
28842892
}
28852893

2886-
return nullptr;
2894+
return MetadataOrPack();
28872895
}
28882896

28892897
const WitnessTable *
@@ -3009,7 +3017,8 @@ static void _gatherWrittenGenericArgs(
30093017
req.getMangledTypeName(),
30103018
(const void * const *)allGenericArgs.data(),
30113019
[&substitutions](unsigned depth, unsigned index) {
3012-
return substitutions.getMetadata(depth, index);
3020+
// FIXME: Variadic generics
3021+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
30133022
},
30143023
[&substitutions](const Metadata *type, unsigned index) {
30153024
return substitutions.getWitnessTable(type, index);

stdlib/public/runtime/Private.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -442,7 +442,7 @@ class TypeInfo {
442442

443443
const void * const *getGenericArgs() const { return genericArgs; }
444444

445-
const Metadata *getMetadata(unsigned depth, unsigned index) const;
445+
MetadataOrPack getMetadata(unsigned depth, unsigned index) const;
446446
const WitnessTable *getWitnessTable(const Metadata *type,
447447
unsigned index) const;
448448
};

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 111 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -332,7 +332,8 @@ ProtocolConformanceDescriptor::getWitnessTable(const Metadata *type) const {
332332
auto error = _checkGenericRequirements(
333333
getConditionalRequirements(), conditionalArgs,
334334
[&substitutions](unsigned depth, unsigned index) {
335-
return substitutions.getMetadata(depth, index);
335+
// FIXME: Variadic generics
336+
return substitutions.getMetadata(depth, index).getMetadataOrNull();
336337
},
337338
[&substitutions](const Metadata *type, unsigned index) {
338339
return substitutions.getWitnessTable(type, index);
@@ -1400,16 +1401,121 @@ checkGenericRequirement(const GenericRequirementDescriptor &req,
14001401
(unsigned)req.getKind());
14011402
}
14021403

1404+
static llvm::Optional<TypeLookupError>
1405+
checkGenericPackRequirement(const GenericRequirementDescriptor &req,
1406+
llvm::SmallVectorImpl<const void *> &extraArguments,
1407+
SubstGenericParameterFn substGenericParam,
1408+
SubstDependentWitnessTableFn substWitnessTable) {
1409+
assert(req.getFlags().isPackRequirement());
1410+
1411+
// Make sure we understand the requirement we're dealing with.
1412+
if (!req.hasKnownKind())
1413+
return TypeLookupError("unknown kind");
1414+
1415+
// Resolve the subject generic parameter.
1416+
auto result = swift::getTypePackByMangledName(
1417+
req.getParam(), extraArguments.data(),
1418+
substGenericParam, substWitnessTable);
1419+
if (result.getError())
1420+
return *result.getError();
1421+
MetadataPackPointer subjectType = result.getType();
1422+
assert(subjectType.getLifetime() == PackLifetime::OnHeap);
1423+
1424+
// Check the requirement.
1425+
switch (req.getKind()) {
1426+
case GenericRequirementKind::Protocol: {
1427+
llvm::SmallVector<const WitnessTable *, 4> witnessTables;
1428+
1429+
// Look up the conformance of each pack element to the protocol.
1430+
for (unsigned i = 0, e = subjectType.getNumElements(); i < e; ++i) {
1431+
const Metadata *elt = subjectType.getElements()[i];
1432+
1433+
const WitnessTable *witnessTable = nullptr;
1434+
if (!_conformsToProtocol(nullptr, elt, req.getProtocol(),
1435+
&witnessTable)) {
1436+
const char *protoName =
1437+
req.getProtocol() ? req.getProtocol().getName() : "<null>";
1438+
return TYPE_LOOKUP_ERROR_FMT(
1439+
"subject type %.*s does not conform to protocol %s",
1440+
(int)req.getParam().size(), req.getParam().data(), protoName);
1441+
}
1442+
1443+
if (req.getProtocol().needsWitnessTable())
1444+
witnessTables.push_back(witnessTable);
1445+
}
1446+
1447+
// If we need a witness table, add it.
1448+
if (req.getProtocol().needsWitnessTable()) {
1449+
assert(witnessTables.size() == subjectType.getNumElements());
1450+
auto *pack = swift_allocateWitnessTablePack(witnessTables.data(),
1451+
witnessTables.size());
1452+
extraArguments.push_back(pack);
1453+
}
1454+
1455+
return llvm::None;
1456+
}
1457+
1458+
case GenericRequirementKind::SameType: {
1459+
llvm_unreachable("Implement me");
1460+
}
1461+
1462+
case GenericRequirementKind::Layout: {
1463+
llvm_unreachable("Implement me");
1464+
}
1465+
1466+
case GenericRequirementKind::BaseClass: {
1467+
llvm_unreachable("Implement me");
1468+
}
1469+
1470+
case GenericRequirementKind::SameConformance: {
1471+
// FIXME: Implement this check.
1472+
return llvm::None;
1473+
}
1474+
1475+
case GenericRequirementKind::SameShape: {
1476+
auto result = swift::getTypePackByMangledName(
1477+
req.getParam(), extraArguments.data(),
1478+
substGenericParam, substWitnessTable);
1479+
if (result.getError())
1480+
return *result.getError();
1481+
MetadataPackPointer otherType = result.getType();
1482+
assert(otherType.getLifetime() == PackLifetime::OnHeap);
1483+
1484+
if (subjectType.getNumElements() != otherType.getNumElements()) {
1485+
return TYPE_LOOKUP_ERROR_FMT("same-shape requirement unsatisfied; "
1486+
"%lu != %lu",
1487+
subjectType.getNumElements(),
1488+
otherType.getNumElements() );
1489+
}
1490+
1491+
return llvm::None;
1492+
}
1493+
}
1494+
1495+
// Unknown generic requirement kind.
1496+
return TYPE_LOOKUP_ERROR_FMT("unknown generic requirement kind %u",
1497+
(unsigned)req.getKind());
1498+
}
1499+
14031500
llvm::Optional<TypeLookupError> swift::_checkGenericRequirements(
14041501
llvm::ArrayRef<GenericRequirementDescriptor> requirements,
14051502
llvm::SmallVectorImpl<const void *> &extraArguments,
14061503
SubstGenericParameterFn substGenericParam,
14071504
SubstDependentWitnessTableFn substWitnessTable) {
14081505
for (const auto &req : requirements) {
1409-
auto error = checkGenericRequirement(req, extraArguments,
1410-
substGenericParam, substWitnessTable);
1411-
if (error)
1412-
return error;
1506+
if (req.getFlags().isPackRequirement()) {
1507+
auto error = checkGenericPackRequirement(req, extraArguments,
1508+
substGenericParam,
1509+
substWitnessTable);
1510+
if (error)
1511+
return error;
1512+
} else {
1513+
auto error = checkGenericRequirement(req, extraArguments,
1514+
substGenericParam,
1515+
substWitnessTable);
1516+
if (error)
1517+
return error;
1518+
}
14131519
}
14141520

14151521
// Success!

stdlib/public/runtime/ReflectionMirror.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -379,7 +379,8 @@ getFieldAt(const Metadata *base, unsigned index) {
379379
auto result = swift_getTypeByMangledName(
380380
MetadataState::Complete, typeName, substitutions.getGenericArgs(),
381381
[&substitutions](unsigned depth, unsigned index) {
382-
return substitutions.getMetadata(depth, index);
382+
// FIXME: Variadic generics
383+
return substitutions.getMetadata(depth, index).getMetadata();
383384
},
384385
[&substitutions](const Metadata *type, unsigned index) {
385386
return substitutions.getWitnessTable(type, index);

0 commit comments

Comments
 (0)