Skip to content

Commit eede7e4

Browse files
committed
Sema: Move some code from BindingSet::finalize() to BindingSet::inferTransitiveBindings()
1 parent 53d802a commit eede7e4

File tree

1 file changed

+36
-37
lines changed

1 file changed

+36
-37
lines changed

lib/Sema/CSBindings.cpp

Lines changed: 36 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -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

630665
static Type getKeyPathType(ASTContext &ctx, KeyPathCapability capability,
@@ -665,45 +700,9 @@ static Type getKeyPathType(ASTContext &ctx, KeyPathCapability capability,
665700
}
666701

667702
bool 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

Comments
 (0)