Skip to content

Commit 295c981

Browse files
committed
Overloading resolution: prefer directly applicable methods
If directly applicable alternatives exists, do not try other alternatives. The original motivation for this change was to reduce the number of searches for implicit views we do since some overloaded methods like `Int#+` are used a lot, but it turns out that this also makes more code compile (see `overload_directly_applicable.scala` for an example), this change does not seem to match what the specification says (it does not define a notion of "directly applicable") but it does match the behavior of scalac, and it seems useful in general.
1 parent 044d29d commit 295c981

File tree

3 files changed

+27
-4
lines changed

3 files changed

+27
-4
lines changed

src/dotty/tools/dotc/typer/Applications.scala

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1146,11 +1146,17 @@ trait Applications extends Compatibility { self: Typer =>
11461146
alts
11471147
}
11481148

1149-
def narrowByTrees(alts: List[TermRef], args: List[Tree], resultType: Type): List[TermRef] =
1150-
alts filter ( alt =>
1151-
if (!ctx.isAfterTyper) isApplicable(alt, targs, args, resultType)
1152-
else isDirectlyApplicable(alt, targs, args, resultType)
1149+
def narrowByTrees(alts: List[TermRef], args: List[Tree], resultType: Type): List[TermRef] = {
1150+
val alts2 = alts.filter(alt =>
1151+
isDirectlyApplicable(alt, targs, args, resultType)
11531152
)
1153+
if (alts2.isEmpty && !ctx.isAfterTyper)
1154+
alts.filter(alt =>
1155+
isApplicable(alt, targs, args, resultType)
1156+
)
1157+
else
1158+
alts2
1159+
}
11541160

11551161
val alts1 = narrowBySize(alts)
11561162
//ctx.log(i"narrowed by size: ${alts1.map(_.symbol.showDcl)}%, %")
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
C1
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
class A
2+
class B
3+
4+
class C1 {
5+
def f(x: A): Unit = println("C1")
6+
}
7+
class C2 extends C1 {
8+
def f(x: B): Unit = println("C2")
9+
}
10+
11+
object Test extends C2 {
12+
implicit def a2b(x: A): B = new B
13+
def main(args: Array[String]): Unit = {
14+
f(new A)
15+
}
16+
}

0 commit comments

Comments
 (0)