Scala compiler unable to overload methods with type parameters

There seems to be a problem where scalac is unable to overload methods using implicit classes if the method has a type parameter, even though there isn’t anything in the spec that should forbid this. Originally this was pasted as a stackoverflow question here https://stackoverflow.com/questions/58429854/scala-overloading-method-in-implicit-class however thanks to @martijnhoekstra, he managed to minimize the actual issue here https://scastie.scala-lang.org/C95VbD5dS7OCuqqsDbD5tA code from the scastie is pasted below

class Test {
  def rawr(string: String): String = string
}

implicit final class RawrExt(val t: Test) {
  def rawr(int: Int): Int = int
}

val t = new Test

t.rawr(5)


class TestP {
  def rawr[A](list: List[A]): List[A] = list
}

implicit final class RawrExtP(val t: TestP) {
  def rawr(int: Int): Int = int
}

val tt = new TestP

tt.rawr(5) // This doesn't compile

Basically overloading works fine if you have a method without type parameters, i.e. def rawr(int: Int): Int but as soon as the method does have type parameters, i.e. def rawr[A](list: List[A]): List[A] then it doesn’t work.

Does anyone have any ideas as to why this is the case?

The spec section 5.3 doesn’t seem to have any problems with type parameters:

in a selection e.m(args) with e of type T, if the selector m denotes some member(s) of T, but none of these members is applicable to the arguments args. In this case a view v is searched which is applicable to e and whose result contains a method m which is applicable to args. The search proceeds as in the case of implicit parameters, where the implicit scope is the one of T. If such a view is found, the selection e.m is converted to v(e).m(args) .

2 Likes

Would be fixed by https://github.com/scala/scala/pull/7396, but I didn’t finish it in time for 2.13.0. (I tried your test case on that branch and it compiles.)

4 Likes

@adriaanm How hard would it be to backport this to Scala 2.12.x?

3 Likes