mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
[CSOptimizer] Score all of the overload choices matching on literals uniformly
Regardless of whether an overload choice matched on one or more literal candidate types assign it a fixed score to make sure that we always prefer outmost disjunction in cases like `test(1 + 2 + 3)` since it gives us a better chance to prune once there is a contextual type.
This commit is contained in:
@@ -268,6 +268,19 @@ static Constraint *determineBestChoicesInContext(
|
||||
resultTypes.push_back(resultType);
|
||||
}
|
||||
|
||||
// Determine whether all of the argument candidates are inferred from literals.
|
||||
// This information is going to be used later on when we need to decide how to
|
||||
// score a matching choice.
|
||||
bool onlyLiteralCandidates =
|
||||
argFuncType->getNumParams() > 0 &&
|
||||
llvm::none_of(
|
||||
indices(argFuncType->getParams()), [&](const unsigned argIdx) {
|
||||
auto &candidates = candidateArgumentTypes[argIdx];
|
||||
return llvm::any_of(candidates, [&](const auto &candidate) {
|
||||
return !candidate.second;
|
||||
});
|
||||
});
|
||||
|
||||
// Match arguments to the given overload choice.
|
||||
auto matchArguments = [&](OverloadChoice choice, FunctionType *overloadType)
|
||||
-> std::optional<MatchCallArgumentResult> {
|
||||
@@ -592,6 +605,18 @@ static Constraint *determineBestChoicesInContext(
|
||||
// parameters.
|
||||
score /= (overloadType->getNumParams() - numDefaulted);
|
||||
|
||||
// Make sure that the score is uniform for all disjunction
|
||||
// choices that match on literals only, this would make sure that
|
||||
// in operator chains that consist purely of literals we'd
|
||||
// always prefer outermost disjunction instead of innermost
|
||||
// one.
|
||||
//
|
||||
// Preferring outer disjunction first works better in situations
|
||||
// when contextual type for the whole chain becomes available at
|
||||
// some point during solving at it would allow for faster pruning.
|
||||
if (score > 0 && onlyLiteralCandidates)
|
||||
score = 0.1;
|
||||
|
||||
// If one of the result types matches exactly, that's a good
|
||||
// indication that overload choice should be favored.
|
||||
//
|
||||
|
||||
Reference in New Issue
Block a user