On 11/13/12 11:43, Dinko Srkoc wrote:
> import language.dynamics
>
> class C(v: Any) extends Dynamic {
> def selectDynamic[T](n: String): Option[T] = Option(v.asInstanceOf[T])
> def applyDynamic[T](n: String)(): Option[T] = Option(v.asInstanceOf[T])
> }
[...]
> scala> new C(42).foo[Int].get
> java.lang.ClassCastException: java.lang.Integer cannot be cast to
> scala.runtime.Nothing$
Looks like a bug to me.
mkInvoke in Typers.scala just ignores the type argument. So, T is
inferred from the outside, and without any other constraints is inferred
as Nothing.
So this works:
scala> new C(42).foo[Int].get : Int
res5: Int = 42
This happens because mkInvoke is called with the following cxTree:
new C.<init>(42).foo[Int].get
Note that the outer element of that tree is a Select(..., "get"), and
that's not handled by the following code:
val (outer, explicitTargs) = cxTree1 match {
case TypeApply(fun, targs) => (fun, targs)
case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
case t => (t, Nil)
}
That can be fixed by adding another case:
val (outer, explicitTargs) = cxTree1 match {
case TypeApply(fun, targs) => (fun, targs)
case Apply(TypeApply(fun, targs), args) => (Apply(fun, args), targs)
case Select(TypeApply(fun, targs), nme) => (Select(fun, nme), targs)
case t => (t, Nil)
}
With that change, the examples work as expected:
scala> new C(42).foo[Int]().get
res0: Int = 42
scala> new C(42).foo[Int].get
res1: Int = 42