Reputation: 558
I was playing around with Scala's structural types when I discovered what looks like a bug to me. Here is my code:
type toD = { def toDouble: Double }
def foo(t: toD) = t.toDouble
foo(5)
And I got this error:
java.lang.NoSuchMethodException
at scala.runtime.BoxesRunTime.toDouble(Unknown Source)
at .foo(<console>:9)
at .<init>(<console>:11)
at .<clinit>(<console>)
at .<init>(<console>:11)
at .<clinit>(<console>)
at $print(<console>)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:704)
at scala.tools.nsc.interpreter.IMain$Request$$anonfun$14.apply(IMain.scala:920)
at scala.tools.nsc.interpreter.Line$$anonfun$1.apply$mcV$sp(Line.scala:43)
at scala.tools.nsc.io.package$$anon$2.run(package.scala:25)
at java.lang.Thread.run(Unknown Source)
First, I don't know why this isn't working. Second, it's weird that the code compiles just fine and throws an exception at runtime saying that the method doesn't actually exist.
Does anyone have an explanation for this?
Upvotes: 5
Views: 241
Reputation: 24413
I just played around a bit with this and it really seems to be a bug. However it works when you just set the return type to Any:
type toD = { def toDouble: Any }
I think it may have something to do with auto boxing and the way primitives are handled.
edit:
I just found a workaround:
type toD[A] = { def toDouble: A }
def foo[A](x: toD[A])(implicit y: A =:= Double) = x.toDouble
This ensures, that the return value of toDouble (A) is Double
Upvotes: 6