Skip to content

Commit 59109c2

Browse files
committed
[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.
1 parent 6fb6d1c commit 59109c2

File tree

1 file changed

+25
-0
lines changed

1 file changed

+25
-0
lines changed

lib/Sema/CSOptimizer.cpp

+25
Original file line numberDiff line numberDiff line change
@@ -268,6 +268,19 @@ static Constraint *determineBestChoicesInContext(
268268
resultTypes.push_back(resultType);
269269
}
270270

271+
// Determine whether all of the argument candidates are inferred from literals.
272+
// This information is going to be used later on when we need to decide how to
273+
// score a matching choice.
274+
bool onlyLiteralCandidates =
275+
argFuncType->getNumParams() > 0 &&
276+
llvm::none_of(
277+
indices(argFuncType->getParams()), [&](const unsigned argIdx) {
278+
auto &candidates = candidateArgumentTypes[argIdx];
279+
return llvm::any_of(candidates, [&](const auto &candidate) {
280+
return !candidate.second;
281+
});
282+
});
283+
271284
// Match arguments to the given overload choice.
272285
auto matchArguments = [&](OverloadChoice choice, FunctionType *overloadType)
273286
-> std::optional<MatchCallArgumentResult> {
@@ -592,6 +605,18 @@ static Constraint *determineBestChoicesInContext(
592605
// parameters.
593606
score /= (overloadType->getNumParams() - numDefaulted);
594607

608+
// Make sure that the score is uniform for all disjunction
609+
// choices that match on literals only, this would make sure that
610+
// in operator chains that consist purely of literals we'd
611+
// always prefer outermost disjunction instead of innermost
612+
// one.
613+
//
614+
// Preferring outer disjunction first works better in situations
615+
// when contextual type for the whole chain becomes available at
616+
// some point during solving at it would allow for faster pruning.
617+
if (score > 0 && onlyLiteralCandidates)
618+
score = 0.1;
619+
595620
// If one of the result types matches exactly, that's a good
596621
// indication that overload choice should be favored.
597622
//

0 commit comments

Comments
 (0)