@@ -570,6 +570,57 @@ void ModuleDecl::getDisplayDecls(SmallVectorImpl<Decl*> &Results) const {
570570 FORWARD (getDisplayDecls, (Results));
571571}
572572
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+
573624Optional<ProtocolConformanceRef>
574625ModuleDecl::lookupConformance (Type type, ProtocolDecl *protocol) {
575626 ASTContext &ctx = getASTContext ();
@@ -609,52 +660,8 @@ ModuleDecl::lookupConformance(Type type, ProtocolDecl *protocol) {
609660 // An existential conforms to a protocol if the protocol is listed in the
610661 // existential's list of conformances and the existential conforms to
611662 // 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);
658665
659666 // Type variables have trivial conformances.
660667 if (type->isTypeVariableOrMember ())
0 commit comments