Commit d9f5202
committed
Prefer non-varargs methods in overload resolution when tiebreaker
Fixes #24072
Add a tiebreaker in the `compare` method to prefer non-varargs methods over varargs methods when both alternatives are equally specific.
`isAsGood` function normally prefer varargs methods. However, it can fail to distinguish methods when wildcard types are involved with invariant type parameters.
For example:
```scala
def blub[T](a: Class[? <: T]): Unit // m1
def blub[T](a: Class[T], ints: Int*): Unit // m2
blub(classOf[Object])
```
Here, `compare(m1, m2)` returns 0 (ambiguous) because both `winsType1` and `winsType2` are false:
- `m2` is not as good as `m1` (this is correct: a varargs method can only be as good as another varargs method).
- `m1` is NOT as good as the `m2` because Class[? <: T] is not a subtype of Class[T] (Class is invariant)
The new tiebreaker resolves this ambiguities by preferring
non-varargs methods as a final comparison step when owner hierarchy and type-based comparisons don't distinguish the alternatives.1 parent c9309e7 commit d9f5202
File tree
2 files changed
+19
-1
lines changed- compiler/src/dotty/tools/dotc/typer
- tests/run/overload_repeated
2 files changed
+19
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
2176 | 2176 | | |
2177 | 2177 | | |
2178 | 2178 | | |
2179 | | - | |
| 2179 | + | |
| 2180 | + | |
| 2181 | + | |
| 2182 | + | |
| 2183 | + | |
| 2184 | + | |
| 2185 | + | |
| 2186 | + | |
| 2187 | + | |
| 2188 | + | |
| 2189 | + | |
| 2190 | + | |
| 2191 | + | |
| 2192 | + | |
2180 | 2193 | | |
2181 | 2194 | | |
2182 | 2195 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
13 | 13 | | |
14 | 14 | | |
15 | 15 | | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
16 | 20 | | |
17 | 21 | | |
18 | 22 | | |
| |||
28 | 32 | | |
29 | 33 | | |
30 | 34 | | |
| 35 | + | |
31 | 36 | | |
32 | 37 | | |
0 commit comments