@@ -625,6 +625,41 @@ void BindingSet::inferTransitiveBindings() {
625625 /* isTransitive=*/ true );
626626 }
627627 }
628+
629+ if (!hasViableBindings ()) {
630+ if (auto *locator = TypeVar->getImpl ().getLocator ()) {
631+ if (locator->isLastElement <LocatorPathElt::MemberRefBase>()) {
632+ // If this is a base of an unresolved member chain, as a last
633+ // resort effort let's infer base to be a protocol type based
634+ // on contextual conformance requirements.
635+ //
636+ // This allows us to find solutions in cases like this:
637+ //
638+ // \code
639+ // func foo<T: P>(_: T) {}
640+ // foo(.bar) <- `.bar` should be a static member of `P`.
641+ // \endcode
642+ inferTransitiveProtocolRequirements ();
643+
644+ if (TransitiveProtocols.has_value ()) {
645+ for (auto *constraint : *TransitiveProtocols) {
646+ Type protocolTy = constraint->getSecondType ();
647+
648+ // Compiler-known marker protocols cannot be extended with members,
649+ // so do not consider them.
650+ if (auto p = protocolTy->getAs <ProtocolType>()) {
651+ if (ProtocolDecl *decl = p->getDecl ())
652+ if (decl->getKnownProtocolKind () && decl->isMarkerProtocol ())
653+ continue ;
654+ }
655+
656+ addBinding ({protocolTy, AllowedBindingKind::Exact, constraint},
657+ /* isTransitive=*/ false );
658+ }
659+ }
660+ }
661+ }
662+ }
628663}
629664
630665static Type getKeyPathType (ASTContext &ctx, KeyPathCapability capability,
@@ -665,45 +700,9 @@ static Type getKeyPathType(ASTContext &ctx, KeyPathCapability capability,
665700}
666701
667702bool BindingSet::finalize (bool transitive) {
668- if (transitive) {
703+ if (transitive)
669704 inferTransitiveBindings ();
670705
671- if (!hasViableBindings ()) {
672- if (auto *locator = TypeVar->getImpl ().getLocator ()) {
673- if (locator->isLastElement <LocatorPathElt::MemberRefBase>()) {
674- // If this is a base of an unresolved member chain, as a last
675- // resort effort let's infer base to be a protocol type based
676- // on contextual conformance requirements.
677- //
678- // This allows us to find solutions in cases like this:
679- //
680- // \code
681- // func foo<T: P>(_: T) {}
682- // foo(.bar) <- `.bar` should be a static member of `P`.
683- // \endcode
684- inferTransitiveProtocolRequirements ();
685-
686- if (TransitiveProtocols.has_value ()) {
687- for (auto *constraint : *TransitiveProtocols) {
688- Type protocolTy = constraint->getSecondType ();
689-
690- // Compiler-known marker protocols cannot be extended with members,
691- // so do not consider them.
692- if (auto p = protocolTy->getAs <ProtocolType>()) {
693- if (ProtocolDecl *decl = p->getDecl ())
694- if (decl->getKnownProtocolKind () && decl->isMarkerProtocol ())
695- continue ;
696- }
697-
698- addBinding ({protocolTy, AllowedBindingKind::Exact, constraint},
699- /* isTransitive=*/ false );
700- }
701- }
702- }
703- }
704- }
705- }
706-
707706 if (auto *locator = TypeVar->getImpl ().getLocator ()) {
708707 if (TypeVar->getImpl ().isKeyPathType ()) {
709708 auto &ctx = CS.getASTContext ();
0 commit comments