Skip to content

Commit

Permalink
Overloading resolution: prefer directly applicable methods
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
smarter committed Jun 3, 2016
1 parent 044d29d commit 295c981
Show file tree
Hide file tree
Showing 3 changed files with 27 additions and 4 deletions.
14 changes: 10 additions & 4 deletions src/dotty/tools/dotc/typer/Applications.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1146,11 +1146,17 @@ trait Applications extends Compatibility { self: Typer =>
alts
}

def narrowByTrees(alts: List[TermRef], args: List[Tree], resultType: Type): List[TermRef] =
alts filter ( alt =>
if (!ctx.isAfterTyper) isApplicable(alt, targs, args, resultType)
else isDirectlyApplicable(alt, targs, args, resultType)
def narrowByTrees(alts: List[TermRef], args: List[Tree], resultType: Type): List[TermRef] = {
val alts2 = alts.filter(alt =>
isDirectlyApplicable(alt, targs, args, resultType)
)
if (alts2.isEmpty && !ctx.isAfterTyper)
alts.filter(alt =>
isApplicable(alt, targs, args, resultType)
)
else
alts2
}

val alts1 = narrowBySize(alts)
//ctx.log(i"narrowed by size: ${alts1.map(_.symbol.showDcl)}%, %")
Expand Down
1 change: 1 addition & 0 deletions tests/run/overload_directly_applicable.check
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
C1
16 changes: 16 additions & 0 deletions tests/run/overload_directly_applicable.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
class A
class B

class C1 {
def f(x: A): Unit = println("C1")
}
class C2 extends C1 {
def f(x: B): Unit = println("C2")
}

object Test extends C2 {
implicit def a2b(x: A): B = new B
def main(args: Array[String]): Unit = {
f(new A)
}
}

0 comments on commit 295c981

Please sign in to comment.