@@ -338,6 +338,52 @@ static void findFavoredChoicesBasedOnArity(
338
338
favoredChoice (choice);
339
339
}
340
340
341
+ // / Preserves old behavior where, for unary calls, the solver would not previously
342
+ // / consider choices that didn't match on the number of parameters (regardless of
343
+ // / defaults and variadics) and only exact matches were favored.
344
+ static std::optional<DisjunctionInfo> preserveFavoringOfUnlabeledUnaryArgument (
345
+ ConstraintSystem &cs, Constraint *disjunction, ArgumentList *argumentList) {
346
+ if (!argumentList->isUnlabeledUnary ())
347
+ return std::nullopt;
348
+
349
+ auto ODRE = isOverloadedDeclRef (disjunction);
350
+ bool preserveFavoringOfUnlabeledUnaryArgument =
351
+ !ODRE || numOverloadChoicesMatchingOnArity (ODRE, argumentList) < 2 ;
352
+
353
+ if (!preserveFavoringOfUnlabeledUnaryArgument)
354
+ return std::nullopt;
355
+
356
+ auto *argument =
357
+ argumentList->getUnlabeledUnaryExpr ()->getSemanticsProvidingExpr ();
358
+ // The hack operated on "favored" types and only declaration references,
359
+ // applications, and (dynamic) subscripts had them if they managed to
360
+ // get an overload choice selected during constraint generation.
361
+ if (!(isExpr<DeclRefExpr>(argument) || isExpr<ApplyExpr>(argument) ||
362
+ isExpr<SubscriptExpr>(argument) ||
363
+ isExpr<DynamicSubscriptExpr>(argument)))
364
+ return {/* score=*/ 0 };
365
+
366
+ auto argumentType = cs.getType (argument);
367
+ if (argumentType->hasTypeVariable () || argumentType->hasDependentMember ())
368
+ return {/* score=*/ 0 };
369
+
370
+ SmallVector<Constraint *, 2 > favoredChoices;
371
+ forEachDisjunctionChoice (
372
+ cs, disjunction,
373
+ [&argumentType, &favoredChoices](Constraint *choice, ValueDecl *decl,
374
+ FunctionType *overloadType) {
375
+ if (overloadType->getNumParams () != 1 )
376
+ return ;
377
+
378
+ auto paramType = overloadType->getParams ()[0 ].getPlainType ();
379
+ if (paramType->isEqual (argumentType))
380
+ favoredChoices.push_back (choice);
381
+ });
382
+
383
+ return DisjunctionInfo (/* score=*/ favoredChoices.empty () ? 0 : 1 ,
384
+ favoredChoices);
385
+ }
386
+
341
387
} // end anonymous namespace
342
388
343
389
// / Given a set of disjunctions, attempt to determine
@@ -444,6 +490,16 @@ static void determineBestChoicesInContext(
444
490
}
445
491
}
446
492
493
+ // Preserves old behavior where, for unary calls, the solver
494
+ // would not consider choices that didn't match on the number
495
+ // of parameters (regardless of defaults) and only exact
496
+ // matches were favored.
497
+ if (auto info = preserveFavoringOfUnlabeledUnaryArgument (cs, disjunction,
498
+ argumentList)) {
499
+ recordResult (disjunction, std::move (info.value ()));
500
+ continue ;
501
+ }
502
+
447
503
if (!isSupportedDisjunction (disjunction))
448
504
continue ;
449
505
@@ -931,17 +987,6 @@ static void determineBestChoicesInContext(
931
987
double bestScore = 0.0 ;
932
988
SmallVector<std::pair<Constraint *, double >, 2 > favoredChoices;
933
989
934
- // Preserves old behavior where, for unary calls, the solver
935
- // would not consider choices that didn't match on the number
936
- // of parameters (regardless of defaults) and only exact
937
- // matches were favored.
938
- bool preserveFavoringOfUnlabeledUnaryArgument = false ;
939
- if (argumentList->isUnlabeledUnary ()) {
940
- auto ODRE = isOverloadedDeclRef (disjunction);
941
- preserveFavoringOfUnlabeledUnaryArgument =
942
- !ODRE || numOverloadChoicesMatchingOnArity (ODRE, argumentList) < 2 ;
943
- }
944
-
945
990
forEachDisjunctionChoice (
946
991
cs, disjunction,
947
992
[&](Constraint *choice, ValueDecl *decl, FunctionType *overloadType) {
@@ -970,15 +1015,6 @@ static void determineBestChoicesInContext(
970
1015
onlyLiteralCandidates &&
971
1016
(!canUseContextualResultTypes () || resultTypes.empty ());
972
1017
973
- if (preserveFavoringOfUnlabeledUnaryArgument) {
974
- // Old behavior completely disregarded the fact that some of
975
- // the parameters could be defaulted.
976
- if (overloadType->getNumParams () != 1 )
977
- return ;
978
-
979
- favorExactMatchesOnly = true ;
980
- }
981
-
982
1018
// This is important for SIMD operators in particular because
983
1019
// a lot of their overloads have same-type requires to a concrete
984
1020
// type: `<Scalar == (U)Int*>(_: SIMD*<Scalar>, ...) -> ...`.
0 commit comments