@@ -529,6 +529,20 @@ static unsigned numOverloadChoicesMatchingOnArity(OverloadedDeclRefExpr *ODRE,
529
529
});
530
530
}
531
531
532
+ static bool isVariadicGenericOverload (ValueDecl *choice) {
533
+ auto genericContext = choice->getAsGenericContext ();
534
+ if (!genericContext)
535
+ return false ;
536
+
537
+ auto *GPL = genericContext->getGenericParams ();
538
+ if (!GPL)
539
+ return false ;
540
+
541
+ return llvm::any_of (GPL->getParams (), [&](const GenericTypeParamDecl *GP) {
542
+ return GP->isParameterPack ();
543
+ });
544
+ }
545
+
532
546
// / This maintains an "old hack" behavior where overloads of some
533
547
// / `OverloadedDeclRef` calls were favored purely based on number of
534
548
// / argument and (non-defaulted) parameters matching.
@@ -542,20 +556,6 @@ static void findFavoredChoicesBasedOnArity(
542
556
if (numOverloadChoicesMatchingOnArity (ODRE, argumentList) > 1 )
543
557
return ;
544
558
545
- auto isVariadicGenericOverload = [&](ValueDecl *choice) {
546
- auto genericContext = choice->getAsGenericContext ();
547
- if (!genericContext)
548
- return false ;
549
-
550
- auto *GPL = genericContext->getGenericParams ();
551
- if (!GPL)
552
- return false ;
553
-
554
- return llvm::any_of (GPL->getParams (), [&](const GenericTypeParamDecl *GP) {
555
- return GP->isParameterPack ();
556
- });
557
- };
558
-
559
559
bool hasVariadicGenerics = false ;
560
560
SmallVector<Constraint *> favored;
561
561
@@ -591,6 +591,21 @@ static std::optional<DisjunctionInfo> preserveFavoringOfUnlabeledUnaryArgument(
591
591
cs.getParentExpr (argumentList->getUnlabeledUnaryExpr ())))
592
592
return std::nullopt;
593
593
594
+ // The hack rolled back favoring choices if one of the overloads was a
595
+ // protocol requirement or variadic generic.
596
+ //
597
+ // Note that it doesn't matter whether such overload choices are viable
598
+ // or not, their presence disabled this "optimization".
599
+ if (llvm::any_of (disjunction->getNestedConstraints (), [](Constraint *choice) {
600
+ auto *decl = getOverloadChoiceDecl (choice);
601
+ if (!decl)
602
+ return false ;
603
+
604
+ return isa<ProtocolDecl>(decl->getDeclContext ()) ||
605
+ isVariadicGenericOverload (decl);
606
+ }))
607
+ return std::nullopt;
608
+
594
609
auto ODRE = isOverloadedDeclRef (disjunction);
595
610
bool preserveFavoringOfUnlabeledUnaryArgument =
596
611
!ODRE || numOverloadChoicesMatchingOnArity (ODRE, argumentList) < 2 ;
0 commit comments