22//
33// This source file is part of the Swift.org open source project
44//
5- // Copyright (c) 2014 - 2023 Apple Inc. and the Swift project authors
5+ // Copyright (c) 2014 - 2025 Apple Inc. and the Swift project authors
66// Licensed under Apache License v2.0 with Runtime Library Exception
77//
88// See https://swift.org/LICENSE.txt for license information
@@ -527,10 +527,11 @@ static void determineBestChoicesInContext(
527527 // type matches a parameter type (i.e. when partially resolved generic
528528 // types are matched) this function is going to produce \c std::nullopt
529529 // instead of `0` that indicates "not a match".
530- std::function<std::optional<double >(GenericSignature, Type , Type,
531- MatchOptions)>
530+ std::function<std::optional<double >(GenericSignature, ValueDecl * , Type,
531+ Type, MatchOptions)>
532532 scoreCandidateMatch =
533- [&](GenericSignature genericSig, Type candidateType, Type paramType,
533+ [&](GenericSignature genericSig, ValueDecl *choice,
534+ Type candidateType, Type paramType,
534535 MatchOptions options) -> std::optional<double > {
535536 auto areEqual = [&](Type a, Type b) {
536537 return a->getDesugaredType ()->isEqual (b->getDesugaredType ());
@@ -618,13 +619,12 @@ static void determineBestChoicesInContext(
618619
619620 if (!candidateOptionals.empty () || !paramOptionals.empty ()) {
620621 if (paramOptionals.size () >= candidateOptionals.size ()) {
621- auto score = scoreCandidateMatch (genericSig, candidateType,
622+ auto score = scoreCandidateMatch (genericSig, choice, candidateType,
622623 paramType, options);
623624 // Injection lowers the score slightly to comply with
624625 // old behavior where exact matches on operator parameter
625626 // types were always preferred.
626- return score == 1 && isOperatorDisjunction (disjunction) ? 0.9
627- : score;
627+ return score == 1 && choice->isOperator () ? 0.9 : score;
628628 }
629629
630630 // Optionality mismatch.
@@ -746,7 +746,7 @@ static void determineBestChoicesInContext(
746746 // everything else the solver should try both concrete and
747747 // generic and disambiguate during ranking.
748748 if (result == CheckRequirementsResult::Success)
749- return isOperatorDisjunction (disjunction ) ? 0.9 : 1.0 ;
749+ return choice-> isOperator ( ) ? 0.9 : 1.0 ;
750750
751751 return 0 ;
752752 }
@@ -914,7 +914,7 @@ static void determineBestChoicesInContext(
914914 options |= MatchFlag::DisableCGFloatDoubleConversion;
915915
916916 auto candidateScore = scoreCandidateMatch (
917- genericSig, candidateType, paramType, options);
917+ genericSig, decl, candidateType, paramType, options);
918918
919919 if (!candidateScore)
920920 continue ;
@@ -958,7 +958,7 @@ static void determineBestChoicesInContext(
958958 // Preferring outer disjunction first works better in situations
959959 // when contextual type for the whole chain becomes available at
960960 // some point during solving at it would allow for faster pruning.
961- if (score > 0 && onlyLiteralCandidates)
961+ if (score > 0 && onlyLiteralCandidates && decl-> isOperator () )
962962 score = 0.1 ;
963963
964964 // If one of the result types matches exactly, that's a good
@@ -984,7 +984,7 @@ static void determineBestChoicesInContext(
984984 ->isCGFloat ())
985985 return false ;
986986
987- return scoreCandidateMatch (genericSig,
987+ return scoreCandidateMatch (genericSig, decl,
988988 overloadType->getResult (),
989989 candidateResultTy,
990990 /* options=*/ {}) > 0 ;
0 commit comments