Skip to content

Commit ef2be0d

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 2520d40 commit ef2be0d

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
@@ -1846,6 +1846,24 @@ ConstraintSystem::selectDisjunction() {
18461846
// based on number of favored/active choices.
18471847
if (*firstScore != *secondScore)
18481848
return *firstScore > *secondScore;
1849+
1850+
// If the scores are the same and both disjunctions are operators
1851+
// they could be ranked purely based on whether the candidates
1852+
// were speculative or not. The one with more context always wins.
1853+
//
1854+
// Consider the following situation:
1855+
//
1856+
// func test(_: Int) { ... }
1857+
// func test(_: String) { ... }
1858+
//
1859+
// test("a" + "b" + "c")
1860+
//
1861+
// In this case we should always prefer ... + "c" over "a" + "b"
1862+
// because it would fail and prune the other overload if parameter
1863+
// type (aka contextual type) is `Int`.
1864+
if (isFirstOperator && isSecondOperator &&
1865+
isFirstSpeculative != isSecondSpeculative)
1866+
return isSecondSpeculative;
18491867
}
18501868

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

0 commit comments

Comments
 (0)