@@ -570,6 +570,57 @@ void ModuleDecl::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const {
570
570
FORWARD (getDisplayDecls, (Results));
571
571
}
572
572
573
+ Optional<ProtocolConformanceRef>
574
+ ModuleDecl::lookupExistentialConformance (Type type, ProtocolDecl *protocol) {
575
+ assert (type->isExistentialType ());
576
+
577
+ // If the existential type cannot be represented or the protocol does not
578
+ // conform to itself, there's no point in looking further.
579
+ if (!protocol->existentialConformsToSelf ())
580
+ return None;
581
+
582
+ auto layout = type->getExistentialLayout ();
583
+
584
+ // Due to an IRGen limitation, witness tables cannot be passed from an
585
+ // existential to an archetype parameter, so for now we restrict this to
586
+ // @objc protocols.
587
+ if (!layout.isObjC ()) {
588
+ return None;
589
+ }
590
+
591
+ // If the existential is class-constrained, the class might conform
592
+ // concretely.
593
+ if (auto superclass = layout.explicitSuperclass ) {
594
+ if (auto result = lookupConformance (superclass, protocol))
595
+ return result;
596
+ }
597
+
598
+ // Otherwise, the existential might conform abstractly.
599
+ for (auto proto : layout.getProtocols ()) {
600
+ auto *protoDecl = proto->getDecl ();
601
+
602
+ // If we found the protocol we're looking for, return an abstract
603
+ // conformance to it.
604
+ if (protoDecl == protocol)
605
+ return ProtocolConformanceRef (protocol);
606
+
607
+ // If the protocol has a superclass constraint, we might conform
608
+ // concretely.
609
+ if (auto superclass = protoDecl->getSuperclass ()) {
610
+ if (auto result = lookupConformance (superclass, protocol))
611
+ return result;
612
+ }
613
+
614
+ // Now check refined protocols.
615
+ if (protoDecl->inheritsFrom (protocol))
616
+ return ProtocolConformanceRef (protocol);
617
+ }
618
+
619
+ // We didn't find our protocol in the existential's list; it doesn't
620
+ // conform.
621
+ return None;
622
+ }
623
+
573
624
Optional<ProtocolConformanceRef>
574
625
ModuleDecl::lookupConformance (Type type, ProtocolDecl *protocol) {
575
626
ASTContext &ctx = getASTContext ();
@@ -609,52 +660,8 @@ ModuleDecl::lookupConformance(Type type, ProtocolDecl *protocol) {
609
660
// An existential conforms to a protocol if the protocol is listed in the
610
661
// existential's list of conformances and the existential conforms to
611
662
// itself.
612
- if (type->isExistentialType ()) {
613
- // If the existential type cannot be represented or the protocol does not
614
- // conform to itself, there's no point in looking further.
615
- if (!protocol->existentialConformsToSelf ())
616
- return None;
617
-
618
- auto layout = type->getExistentialLayout ();
619
-
620
- // Due to an IRGen limitation, witness tables cannot be passed from an
621
- // existential to an archetype parameter, so for now we restrict this to
622
- // @objc protocols.
623
- if (!layout.isObjC ())
624
- return None;
625
-
626
- // If the existential is class-constrained, the class might conform
627
- // concretely.
628
- if (auto superclass = layout.explicitSuperclass ) {
629
- if (auto result = lookupConformance (superclass, protocol))
630
- return result;
631
- }
632
-
633
- // Otherwise, the existential might conform abstractly.
634
- for (auto proto : layout.getProtocols ()) {
635
- auto *protoDecl = proto->getDecl ();
636
-
637
- // If we found the protocol we're looking for, return an abstract
638
- // conformance to it.
639
- if (protoDecl == protocol)
640
- return ProtocolConformanceRef (protocol);
641
-
642
- // If the protocol has a superclass constraint, we might conform
643
- // concretely.
644
- if (auto superclass = protoDecl->getSuperclass ()) {
645
- if (auto result = lookupConformance (superclass, protocol))
646
- return result;
647
- }
648
-
649
- // Now check refined protocols.
650
- if (protoDecl->inheritsFrom (protocol))
651
- return ProtocolConformanceRef (protocol);
652
- }
653
-
654
- // We didn't find our protocol in the existential's list; it doesn't
655
- // conform.
656
- return None;
657
- }
663
+ if (type->isExistentialType ())
664
+ return lookupExistentialConformance (type, protocol);
658
665
659
666
// Type variables have trivial conformances.
660
667
if (type->isTypeVariableOrMember ())
0 commit comments