@@ -2550,14 +2550,23 @@ struct SortedDeclList {
2550
2550
2551
2551
} // end namespace
2552
2552
2553
- ArrayRef<Decl *>
2554
- ABIMembersRequest::evaluate (
2555
- Evaluator &evaluator, IterableDeclContext *idc) const {
2553
+ namespace {
2554
+ enum class MembersRequestKind {
2555
+ ABI,
2556
+ All,
2557
+ };
2558
+
2559
+ }
2560
+
2561
+ // / Evaluate a request for a particular set of members of an iterable
2562
+ // / declaration context.
2563
+ static ArrayRef<Decl *> evaluateMembersRequest (
2564
+ IterableDeclContext *idc, MembersRequestKind kind) {
2556
2565
auto dc = cast<DeclContext>(idc->getDecl ());
2557
- auto &Context = dc->getASTContext ();
2566
+ auto &ctx = dc->getASTContext ();
2558
2567
SmallVector<Decl *, 8 > result;
2559
2568
2560
- // Esnure that we add any synthesized members.
2569
+ // Ensure that we add any synthesized members.
2561
2570
if (dc->getParentSourceFile ()) {
2562
2571
auto nominal = dyn_cast<NominalTypeDecl>(idc);
2563
2572
@@ -2567,20 +2576,43 @@ ABIMembersRequest::evaluate(
2567
2576
TypeChecker::addImplicitConstructors (nominal);
2568
2577
}
2569
2578
2570
- // Force any derivable conformances in this context. This ensures that any
2571
- // synthesized members will approach in the member list.
2579
+ // Force any conformances that may introduce more members.
2572
2580
for (auto conformance : idc->getLocalConformances ()) {
2573
- if (conformance->getState () == ProtocolConformanceState::Incomplete &&
2574
- conformance->getProtocol ()->getKnownDerivableProtocolKind ())
2575
- TypeChecker::checkConformance (conformance->getRootNormalConformance ());
2581
+ auto proto = conformance->getProtocol ();
2582
+ bool isDerivable =
2583
+ conformance->getState () == ProtocolConformanceState::Incomplete &&
2584
+ proto->getKnownDerivableProtocolKind ();
2585
+
2586
+ switch (kind) {
2587
+ case MembersRequestKind::ABI:
2588
+ // Force any derivable conformances in this context.
2589
+ if (isDerivable)
2590
+ break ;
2591
+
2592
+ continue ;
2593
+
2594
+ case MembersRequestKind::All:
2595
+ // Force any derivable conformances.
2596
+ if (isDerivable)
2597
+ break ;
2598
+
2599
+ // If there are any associated types in the protocol, they might add
2600
+ // type aliases here.
2601
+ if (!proto->getAssociatedTypeMembers ().empty ())
2602
+ break ;
2603
+
2604
+ continue ;
2605
+ }
2606
+
2607
+ TypeChecker::checkConformance (conformance->getRootNormalConformance ());
2576
2608
}
2577
2609
2578
2610
// If the type conforms to Encodable or Decodable, even via an extension,
2579
2611
// the CodingKeys enum is synthesized as a member of the type itself.
2580
2612
// Force it into existence.
2581
2613
if (nominal) {
2582
2614
(void ) evaluateOrDefault (
2583
- Context .evaluator ,
2615
+ ctx .evaluator ,
2584
2616
ResolveImplicitMemberRequest{nominal,
2585
2617
ImplicitMemberAction::ResolveCodingKeys},
2586
2618
{});
@@ -2589,7 +2621,7 @@ ABIMembersRequest::evaluate(
2589
2621
// If the decl has a @main attribute, we need to force synthesis of the
2590
2622
// $main function.
2591
2623
(void ) evaluateOrDefault (
2592
- Context .evaluator ,
2624
+ ctx .evaluator ,
2593
2625
SynthesizeMainFunctionRequest{const_cast <Decl *>(idc->getDecl ())},
2594
2626
nullptr );
2595
2627
@@ -2633,7 +2665,19 @@ ABIMembersRequest::evaluate(
2633
2665
result.push_back (pair.second );
2634
2666
}
2635
2667
2636
- return Context.AllocateCopy (result);
2668
+ return ctx.AllocateCopy (result);
2669
+ }
2670
+
2671
+ ArrayRef<Decl *>
2672
+ ABIMembersRequest::evaluate (
2673
+ Evaluator &evaluator, IterableDeclContext *idc) const {
2674
+ return evaluateMembersRequest (idc, MembersRequestKind::ABI);
2675
+ }
2676
+
2677
+ ArrayRef<Decl *>
2678
+ AllMembersRequest::evaluate (
2679
+ Evaluator &evaluator, IterableDeclContext *idc) const {
2680
+ return evaluateMembersRequest (idc, MembersRequestKind::All);
2637
2681
}
2638
2682
2639
2683
bool TypeChecker::isPassThroughTypealias (TypeAliasDecl *typealias,
0 commit comments