Skip to content

Commit dd26b28

Browse files
committed
[Type checker] Ensure we sort semantic members properly.
When evaluating the semantic members request, we would sort the members before we return them to ensure a stable ordering for (e.g.) vtable layout. However, when not in a source file, we would assume that the resulting members were always sorted. However, they are not always sorted, because we write the iterative decl contexts directly rather than writing the semantic members. Fixes rdar://72833032. (cherry picked from commit 5426117)
1 parent d864e95 commit dd26b28

File tree

1 file changed

+43
-45
lines changed

1 file changed

+43
-45
lines changed

lib/Sema/TypeCheckDecl.cpp

Lines changed: 43 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -2557,51 +2557,49 @@ SemanticMembersRequest::evaluate(Evaluator &evaluator,
25572557
auto &Context = dc->getASTContext();
25582558
SmallVector<Decl *, 8> result;
25592559

2560-
if (!dc->getParentSourceFile()) {
2561-
auto members = idc->getMembers();
2562-
result.append(members.begin(), members.end());
2563-
return Context.AllocateCopy(result);
2564-
}
2565-
2566-
auto nominal = dyn_cast<NominalTypeDecl>(idc);
2567-
2568-
if (nominal) {
2569-
// We need to add implicit initializers because they
2570-
// affect vtable layout.
2571-
TypeChecker::addImplicitConstructors(nominal);
2572-
}
2573-
2574-
// Force any derivable conformances in this context. This ensures that any
2575-
// synthesized members will approach in the member list.
2576-
for (auto conformance : idc->getLocalConformances()) {
2577-
if (conformance->getState() == ProtocolConformanceState::Incomplete &&
2578-
conformance->getProtocol()->getKnownDerivableProtocolKind())
2579-
TypeChecker::checkConformance(conformance->getRootNormalConformance());
2580-
}
2581-
2582-
// If the type conforms to Encodable or Decodable, even via an extension,
2583-
// the CodingKeys enum is synthesized as a member of the type itself.
2584-
// Force it into existence.
2585-
if (nominal) {
2586-
(void) evaluateOrDefault(Context.evaluator,
2587-
ResolveImplicitMemberRequest{nominal,
2588-
ImplicitMemberAction::ResolveCodingKeys},
2589-
{});
2590-
}
2591-
2592-
// If the decl has a @main attribute, we need to force synthesis of the
2593-
// $main function.
2594-
(void) evaluateOrDefault(
2595-
Context.evaluator,
2596-
SynthesizeMainFunctionRequest{const_cast<Decl *>(idc->getDecl())},
2597-
nullptr);
2598-
2599-
for (auto *member : idc->getMembers()) {
2600-
if (auto *var = dyn_cast<VarDecl>(member)) {
2601-
// The projected storage wrapper ($foo) might have dynamically-dispatched
2602-
// accessors, so force them to be synthesized.
2603-
if (var->hasAttachedPropertyWrapper())
2604-
(void) var->getPropertyWrapperBackingProperty();
2560+
// Esnure that we add any synthesized members.
2561+
if (dc->getParentSourceFile()) {
2562+
auto nominal = dyn_cast<NominalTypeDecl>(idc);
2563+
2564+
if (nominal) {
2565+
// We need to add implicit initializers because they
2566+
// affect vtable layout.
2567+
TypeChecker::addImplicitConstructors(nominal);
2568+
}
2569+
2570+
// Force any derivable conformances in this context. This ensures that any
2571+
// synthesized members will approach in the member list.
2572+
for (auto conformance : idc->getLocalConformances()) {
2573+
if (conformance->getState() == ProtocolConformanceState::Incomplete &&
2574+
conformance->getProtocol()->getKnownDerivableProtocolKind())
2575+
TypeChecker::checkConformance(conformance->getRootNormalConformance());
2576+
}
2577+
2578+
// If the type conforms to Encodable or Decodable, even via an extension,
2579+
// the CodingKeys enum is synthesized as a member of the type itself.
2580+
// Force it into existence.
2581+
if (nominal) {
2582+
(void) evaluateOrDefault(
2583+
Context.evaluator,
2584+
ResolveImplicitMemberRequest{nominal,
2585+
ImplicitMemberAction::ResolveCodingKeys},
2586+
{});
2587+
}
2588+
2589+
// If the decl has a @main attribute, we need to force synthesis of the
2590+
// $main function.
2591+
(void) evaluateOrDefault(
2592+
Context.evaluator,
2593+
SynthesizeMainFunctionRequest{const_cast<Decl *>(idc->getDecl())},
2594+
nullptr);
2595+
2596+
for (auto *member : idc->getMembers()) {
2597+
if (auto *var = dyn_cast<VarDecl>(member)) {
2598+
// The projected storage wrapper ($foo) might have
2599+
// dynamically-dispatched accessors, so force them to be synthesized.
2600+
if (var->hasAttachedPropertyWrapper())
2601+
(void) var->getPropertyWrapperBackingProperty();
2602+
}
26052603
}
26062604
}
26072605

0 commit comments

Comments
 (0)