Skip to content

Commit 4c16107

Browse files
committed
[Constraint solver] Unify overload favoring on getEffectiveOverloadType().
The overload-favoring code had a couple of different ways in which it tried to figure out the parameter lists of a given declaration. Have those all depend on ConstraintSystem::getEffectiveOverloadType(), which deals with the various member/non-member cases uniformly.
1 parent daf4610 commit 4c16107

File tree

1 file changed

+25
-43
lines changed

1 file changed

+25
-43
lines changed

lib/Sema/CSGen.cpp

Lines changed: 25 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -595,12 +595,13 @@ namespace {
595595
/// of the overload set and call arguments.
596596
///
597597
/// \param expr The application.
598-
/// \param isFavored Determine whether the given overload is favored.
598+
/// \param isFavored Determine whether the given overload is favored, passing
599+
/// it the "effective" overload type when it's being called.
599600
/// \param mustConsider If provided, a function to detect the presence of
600601
/// overloads which inhibit any overload from being favored.
601602
void favorCallOverloads(ApplyExpr *expr,
602603
ConstraintSystem &CS,
603-
llvm::function_ref<bool(ValueDecl *)> isFavored,
604+
llvm::function_ref<bool(ValueDecl *, Type)> isFavored,
604605
std::function<bool(ValueDecl *)>
605606
mustConsider = nullptr) {
606607
// Find the type variable associated with the function, if any.
@@ -621,7 +622,7 @@ namespace {
621622
Constraint *firstFavored = nullptr;
622623
for (auto constraint : disjunction->getNestedConstraints()) {
623624
if (!constraint->getOverloadChoice().isDecl())
624-
return;
625+
continue;
625626
auto decl = constraint->getOverloadChoice().getDecl();
626627

627628
if (mustConsider && mustConsider(decl)) {
@@ -632,8 +633,14 @@ namespace {
632633
return;
633634
}
634635

636+
Type overloadType =
637+
CS.getEffectiveOverloadType(constraint->getOverloadChoice(),
638+
/*allowMembers=*/true, CS.DC);
639+
if (!overloadType)
640+
continue;
641+
635642
if (!decl->getAttrs().isUnavailable(CS.getASTContext()) &&
636-
isFavored(decl)) {
643+
isFavored(decl, overloadType)) {
637644
// If we might need to roll back the favored constraints, keep
638645
// track of those we are favoring.
639646
if (mustConsider && !constraint->isFavored())
@@ -650,9 +657,12 @@ namespace {
650657
// result type.
651658
if (numFavoredConstraints == 1) {
652659
auto overloadChoice = firstFavored->getOverloadChoice();
653-
auto overloadType = overloadChoice.getDecl()->getInterfaceType();
654-
auto resultType = overloadType->getAs<AnyFunctionType>()->getResult();
655-
CS.setFavoredType(expr, resultType.getPointer());
660+
auto overloadType =
661+
CS.getEffectiveOverloadType(overloadChoice, /*allowMembers=*/true,
662+
CS.DC);
663+
auto resultType = overloadType->castTo<AnyFunctionType>()->getResult();
664+
if (!resultType->hasTypeParameter())
665+
CS.setFavoredType(expr, resultType.getPointer());
656666
}
657667
}
658668

@@ -695,18 +705,11 @@ namespace {
695705
void favorMatchingUnaryOperators(ApplyExpr *expr,
696706
ConstraintSystem &CS) {
697707
// Determine whether the given declaration is favored.
698-
auto isFavoredDecl = [&](ValueDecl *value) -> bool {
699-
auto valueTy = value->getInterfaceType();
700-
701-
auto fnTy = valueTy->getAs<AnyFunctionType>();
708+
auto isFavoredDecl = [&](ValueDecl *value, Type type) -> bool {
709+
auto fnTy = type->getAs<AnyFunctionType>();
702710
if (!fnTy)
703711
return false;
704712

705-
// Figure out the parameter type.
706-
if (value->getDeclContext()->isTypeContext()) {
707-
fnTy = fnTy->getResult()->castTo<AnyFunctionType>();
708-
}
709-
710713
Type paramTy = FunctionType::composeInput(CS.getASTContext(),
711714
fnTy->getParams(), false);
712715
auto resultTy = fnTy->getResult();
@@ -748,10 +751,8 @@ namespace {
748751
}
749752

750753
// Determine whether the given declaration is favored.
751-
auto isFavoredDecl = [&](ValueDecl *value) -> bool {
752-
auto valueTy = value->getInterfaceType();
753-
754-
if (!valueTy->is<AnyFunctionType>())
754+
auto isFavoredDecl = [&](ValueDecl *value, Type type) -> bool {
755+
if (!type->is<AnyFunctionType>())
755756
return false;
756757

757758
auto paramCount = getParamCount(value);
@@ -766,23 +767,11 @@ namespace {
766767

767768
if (auto favoredTy = CS.getFavoredType(expr->getArg())) {
768769
// Determine whether the given declaration is favored.
769-
auto isFavoredDecl = [&](ValueDecl *value) -> bool {
770-
auto valueTy = value->getInterfaceType();
771-
772-
auto fnTy = valueTy->getAs<AnyFunctionType>();
770+
auto isFavoredDecl = [&](ValueDecl *value, Type type) -> bool {
771+
auto fnTy = type->getAs<AnyFunctionType>();
773772
if (!fnTy)
774773
return false;
775774

776-
// Figure out the parameter type, accounting for the implicit 'self' if
777-
// necessary.
778-
if (auto *FD = dyn_cast<AbstractFunctionDecl>(value)) {
779-
if (FD->hasImplicitSelfDecl()) {
780-
if (auto resFnTy = fnTy->getResult()->getAs<AnyFunctionType>()) {
781-
fnTy = resFnTy;
782-
}
783-
}
784-
}
785-
786775
auto paramTy =
787776
AnyFunctionType::composeInput(CS.getASTContext(), fnTy->getParams(),
788777
/*canonicalVararg*/ false);
@@ -841,10 +830,8 @@ namespace {
841830
};
842831

843832
// Determine whether the given declaration is favored.
844-
auto isFavoredDecl = [&](ValueDecl *value) -> bool {
845-
auto valueTy = value->getInterfaceType();
846-
847-
auto fnTy = valueTy->getAs<AnyFunctionType>();
833+
auto isFavoredDecl = [&](ValueDecl *value, Type type) -> bool {
834+
auto fnTy = type->getAs<AnyFunctionType>();
848835
if (!fnTy)
849836
return false;
850837

@@ -870,11 +857,6 @@ namespace {
870857
}
871858
}
872859

873-
// Figure out the parameter type.
874-
if (value->getDeclContext()->isTypeContext()) {
875-
fnTy = fnTy->getResult()->castTo<AnyFunctionType>();
876-
}
877-
878860
auto params = fnTy->getParams();
879861
if (params.size() != 2)
880862
return false;

0 commit comments

Comments
 (0)