Skip to content

Commit a779459

Browse files
committed
[CSOptimizer] Rank operators with the same score based on speculative status
If the scores are the same and both disjunctions are operators they could be ranked purely based on whether the candidates were speculative or not. The one with more context always wins. Consider the following situation: ```swift func test(_: Int) { ... } func test(_: String) { ... } test("a" + "b" + "c") ``` In this case we should always prefer ... + "c" over "a" + "b" because it would fail and prune the other overload if parameter type (aka contextual type) is `Int`.
1 parent 88b207f commit a779459

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

lib/Sema/CSOptimizer.cpp

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1840,6 +1840,24 @@ ConstraintSystem::selectDisjunction() {
18401840
// based on number of favored/active choices.
18411841
if (*firstScore != *secondScore)
18421842
return *firstScore > *secondScore;
1843+
1844+
// If the scores are the same and both disjunctions are operators
1845+
// they could be ranked purely based on whether the candidates
1846+
// were speculative or not. The one with more context always wins.
1847+
//
1848+
// Consider the following situation:
1849+
//
1850+
// func test(_: Int) { ... }
1851+
// func test(_: String) { ... }
1852+
//
1853+
// test("a" + "b" + "c")
1854+
//
1855+
// In this case we should always prefer ... + "c" over "a" + "b"
1856+
// because it would fail and prune the other overload if parameter
1857+
// type (aka contextual type) is `Int`.
1858+
if (isFirstOperator && isSecondOperator &&
1859+
isFirstSpeculative != isSecondSpeculative)
1860+
return isSecondSpeculative;
18431861
}
18441862

18451863
// Use favored choices only if disjunction score is higher

0 commit comments

Comments
 (0)