bug icon indicating copy to clipboard operation
bug copied to clipboard

Wrong overload chosen when there's superclass method that differs only by return-type

Open scabug opened this issue 11 years ago • 2 comments

trait Foo
trait Super {
  def bar(foo: Foo): AnyRef = null
}

object Blub extends Super {
  def bar()(implicit foo: Foo): Int = throw new RuntimeException("BAM!")

  def main(args: Array[String]): Unit =
    println(bar(null))
}

In bytecode both methods bar have the same signature but for the return-type. The call to bar(null) is statically dispatched to the wrong method if the target method is defined in the superclass.

Discovered by [~sirthias].

scabug avatar Nov 27 '14 12:11 scabug

Imported From: https://issues.scala-lang.org/browse/SI-9012?orig=1 Reporter: @jrudolph Affected Versions: 2.10.4, 2.11.4

scabug avatar Nov 27 '14 12:11 scabug

@paulp said: That's quite interesting because bar(null) should NEVER call the Blub-defined method. And indeed if that's the only bar in existence, it doesn't compile at all.

a.scala:10: error: too many arguments for method bar: ()(implicit foo: Foo)Int
    println(bar(null))
               ^
one error found

This is what happens when there is no distinction maintained between the code that you actually wrote vs. the end result of the many meaningless-to-the-programmer transformations which take place on the way to the bytecode.

scabug avatar Dec 07 '14 17:12 scabug