Skip to content

Commit a21b0d9

Browse files
committed
Runtime: Check layout pack requirements in checkGenericPackRequirement()
1 parent d17baed commit a21b0d9

File tree

2 files changed

+34
-14
lines changed

2 files changed

+34
-14
lines changed

stdlib/public/runtime/ProtocolConformance.cpp

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1289,6 +1289,23 @@ static bool isSubclassOrExistential(const Metadata *subclass,
12891289
return isSubclass(subclass, superclass);
12901290
}
12911291

1292+
static llvm::Optional<TypeLookupError>
1293+
satisfiesLayoutConstraint(const GenericRequirementDescriptor &req,
1294+
const Metadata *subjectType) {
1295+
switch (req.getLayout()) {
1296+
case GenericRequirementLayoutKind::Class:
1297+
if (!subjectType->satisfiesClassConstraint()) {
1298+
return TYPE_LOOKUP_ERROR_FMT(
1299+
"subject type %.*s does not satisfy class constraint",
1300+
(int)req.getParam().size(), req.getParam().data());
1301+
}
1302+
return llvm::None;
1303+
}
1304+
1305+
// Unknown layout.
1306+
return TYPE_LOOKUP_ERROR_FMT("unknown layout kind %u", req.getLayout());
1307+
}
1308+
12921309
SWIFT_CC(swift)
12931310
SWIFT_RUNTIME_STDLIB_SPI
12941311
bool swift::_swift_class_isSubclass(const Metadata *subclass,
@@ -1358,18 +1375,7 @@ checkGenericRequirement(const GenericRequirementDescriptor &req,
13581375
}
13591376

13601377
case GenericRequirementKind::Layout: {
1361-
switch (req.getLayout()) {
1362-
case GenericRequirementLayoutKind::Class:
1363-
if (!subjectType->satisfiesClassConstraint()) {
1364-
return TYPE_LOOKUP_ERROR_FMT(
1365-
"subject type %.*s does not satisfy class constraint",
1366-
(int)req.getParam().size(), req.getParam().data());
1367-
}
1368-
return llvm::None;
1369-
}
1370-
1371-
// Unknown layout.
1372-
return TYPE_LOOKUP_ERROR_FMT("unknown layout kind %u", req.getLayout());
1378+
return satisfiesLayoutConstraint(req, subjectType);
13731379
}
13741380

13751381
case GenericRequirementKind::BaseClass: {
@@ -1465,7 +1471,13 @@ checkGenericPackRequirement(const GenericRequirementDescriptor &req,
14651471
}
14661472

14671473
case GenericRequirementKind::Layout: {
1468-
llvm_unreachable("Implement me");
1474+
for (unsigned i = 0, e = subjectType.getNumElements(); i < e; ++i) {
1475+
const Metadata *elt = subjectType.getElements()[i];
1476+
if (auto result = satisfiesLayoutConstraint(req, elt))
1477+
return result;
1478+
}
1479+
1480+
return llvm::None;
14691481
}
14701482

14711483
case GenericRequirementKind::BaseClass: {

test/Interpreter/variadic_generic_types.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,15 @@ types.test("SuperclassReq") {
8282
expectEqual("main.SuperclassReq<Pack{main.Derived, main.Base}>", _typeName(SuperclassReq<Derived, Base>.self))
8383
}
8484

85-
// FIXME: Test layout and same-type pack requirements once more stuff is plumbed through
85+
public struct LayoutReq<each T: AnyObject> {}
86+
87+
types.test("LayoutReq") {
88+
expectEqual("main.LayoutReq<Pack{}>", _typeName(LayoutReq< >.self))
89+
expectEqual("main.LayoutReq<Pack{Swift.AnyObject}>", _typeName(LayoutReq<AnyObject>.self))
90+
expectEqual("main.LayoutReq<Pack{Swift.AnyObject, main.Base}>", _typeName(LayoutReq<AnyObject, Base>.self))
91+
}
92+
93+
// FIXME: Test same-type pack requirements once more stuff is plumbed through
8694

8795
//
8896
// Stored property layout tests

0 commit comments

Comments
 (0)