Skip to content

Commit 344747c

Browse files
committed
Explicitly rely on determinism of serialization for ABI/All members query.
The "synthesized" bit of declarations was never serialized, so sorting deserialized declarations was already a no-op. Make it explicitly a no-op to save some work. The fact that we serialize deterministically is what actually fixed the problem here.
1 parent 5e8ed8d commit 344747c

File tree

1 file changed

+59
-54
lines changed

1 file changed

+59
-54
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 59 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -2566,72 +2566,77 @@ static ArrayRef<Decl *> evaluateMembersRequest(
25662566
auto &ctx = dc->getASTContext();
25672567
SmallVector<Decl *, 8> result;
25682568

2569-
// Ensure that we add any synthesized members.
2570-
if (dc->getParentSourceFile()) {
2571-
auto nominal = dyn_cast<NominalTypeDecl>(idc);
2569+
// If there's no parent source file, everything is already in order.
2570+
if (!dc->getParentSourceFile()) {
2571+
for (auto *member : idc->getMembers())
2572+
result.push_back(member);
25722573

2573-
if (nominal) {
2574-
// We need to add implicit initializers because they
2575-
// affect vtable layout.
2576-
TypeChecker::addImplicitConstructors(nominal);
2577-
}
2574+
return ctx.AllocateCopy(result);
2575+
}
25782576

2579-
// Force any conformances that may introduce more members.
2580-
for (auto conformance : idc->getLocalConformances()) {
2581-
auto proto = conformance->getProtocol();
2582-
bool isDerivable =
2583-
conformance->getState() == ProtocolConformanceState::Incomplete &&
2584-
proto->getKnownDerivableProtocolKind();
2577+
auto nominal = dyn_cast<NominalTypeDecl>(idc);
25852578

2586-
switch (kind) {
2587-
case MembersRequestKind::ABI:
2588-
// Force any derivable conformances in this context.
2589-
if (isDerivable)
2590-
break;
2579+
if (nominal) {
2580+
// We need to add implicit initializers because they
2581+
// affect vtable layout.
2582+
TypeChecker::addImplicitConstructors(nominal);
2583+
}
25912584

2592-
continue;
2585+
// Force any conformances that may introduce more members.
2586+
for (auto conformance : idc->getLocalConformances()) {
2587+
auto proto = conformance->getProtocol();
2588+
bool isDerivable =
2589+
conformance->getState() == ProtocolConformanceState::Incomplete &&
2590+
proto->getKnownDerivableProtocolKind();
25932591

2594-
case MembersRequestKind::All:
2595-
// Force any derivable conformances.
2596-
if (isDerivable)
2597-
break;
2592+
switch (kind) {
2593+
case MembersRequestKind::ABI:
2594+
// Force any derivable conformances in this context.
2595+
if (isDerivable)
2596+
break;
25982597

2599-
// If there are any associated types in the protocol, they might add
2600-
// type aliases here.
2601-
if (!proto->getAssociatedTypeMembers().empty())
2602-
break;
2598+
continue;
26032599

2604-
continue;
2605-
}
2600+
case MembersRequestKind::All:
2601+
// Force any derivable conformances.
2602+
if (isDerivable)
2603+
break;
26062604

2607-
TypeChecker::checkConformance(conformance->getRootNormalConformance());
2608-
}
2605+
// If there are any associated types in the protocol, they might add
2606+
// type aliases here.
2607+
if (!proto->getAssociatedTypeMembers().empty())
2608+
break;
26092609

2610-
// If the type conforms to Encodable or Decodable, even via an extension,
2611-
// the CodingKeys enum is synthesized as a member of the type itself.
2612-
// Force it into existence.
2613-
if (nominal) {
2614-
(void) evaluateOrDefault(
2615-
ctx.evaluator,
2616-
ResolveImplicitMemberRequest{nominal,
2617-
ImplicitMemberAction::ResolveCodingKeys},
2618-
{});
2610+
continue;
26192611
}
26202612

2621-
// If the decl has a @main attribute, we need to force synthesis of the
2622-
// $main function.
2613+
TypeChecker::checkConformance(conformance->getRootNormalConformance());
2614+
}
2615+
2616+
// If the type conforms to Encodable or Decodable, even via an extension,
2617+
// the CodingKeys enum is synthesized as a member of the type itself.
2618+
// Force it into existence.
2619+
if (nominal) {
26232620
(void) evaluateOrDefault(
2624-
ctx.evaluator,
2625-
SynthesizeMainFunctionRequest{const_cast<Decl *>(idc->getDecl())},
2626-
nullptr);
2627-
2628-
for (auto *member : idc->getMembers()) {
2629-
if (auto *var = dyn_cast<VarDecl>(member)) {
2630-
// The projected storage wrapper ($foo) might have
2631-
// dynamically-dispatched accessors, so force them to be synthesized.
2632-
if (var->hasAttachedPropertyWrapper())
2633-
(void) var->getPropertyWrapperBackingProperty();
2634-
}
2621+
ctx.evaluator,
2622+
ResolveImplicitMemberRequest{nominal,
2623+
ImplicitMemberAction::ResolveCodingKeys},
2624+
{});
2625+
}
2626+
2627+
// If the decl has a @main attribute, we need to force synthesis of the
2628+
// $main function.
2629+
(void) evaluateOrDefault(
2630+
ctx.evaluator,
2631+
SynthesizeMainFunctionRequest{const_cast<Decl *>(idc->getDecl())},
2632+
nullptr);
2633+
2634+
for (auto *member : idc->getMembers()) {
2635+
if (auto *var = dyn_cast<VarDecl>(member)) {
2636+
// The projected storage wrapper ($foo) might have
2637+
// dynamically-dispatched accessors, so force them to be synthesized.
2638+
if (var->hasAttachedPropertyWrapper())
2639+
(void) var->getPropertyWrapperBackingProperty();
26352640
}
26362641
}
26372642

0 commit comments

Comments
 (0)