jhegedus
jhegedus

Reputation: 20653

Basic Scala reflection code using recursive types does not compile. Why ? How can it be fixed?

The following Scala code, using the recursive type A does not compile:

package reflection.scala.stackOverflow

import scala.reflect.runtime.universe._

class A[T<:A[T]]

class Question(root:A[_]) {
  val rtmMirror                   =runtimeMirror(getClass.getClassLoader)
  val instanceMirror : InstanceMirror =rtmMirror.reflect(root)
}

It gives the following compilation error:

Error:(9, 50) type arguments [_$1] do not conform to class A's type parameter bounds [T <: reflection.scala.stackOverflow.A[T]]
  val instanceMirror : InstanceMirror =rtmMirror.reflect(root)
                                                 ^
Error:(9, 57) type arguments [_$1] do not conform to class A's type parameter bounds [T <: reflection.scala.stackOverflow.A[T]]
  val instanceMirror : InstanceMirror =rtmMirror.reflect(root)
                                                        ^

Upvotes: 2

Views: 144

Answers (2)

som-snytt
som-snytt

Reputation: 39577

If you really don't care:

scala> import scala.reflect.runtime._
import scala.reflect.runtime._

scala> import universe._
import universe._

scala> class A[T<:A[T]] { def a: T = null.asInstanceOf[T] }
defined class A

scala> def f(x: A[_]) = currentMirror reflect[A[_]] x
f: (x: A[_])reflect.runtime.universe.InstanceMirror

scala> f(new A)
res0: reflect.runtime.universe.InstanceMirror = instance mirror for A@5b369cb9

scala> typeOf[A[_]].member(TermName("a")).asMethod
res1: reflect.runtime.universe.MethodSymbol = method a

scala> res0 reflectMethod res1
res2: reflect.runtime.universe.MethodMirror = method mirror for A.a: T (bound to A@5b369cb9)

scala> res2()
res3: Any = null

I want a black distressed tee that has on the front X[_] and on the back, I dont care what type you think I am. Maybe more strongly worded.

Upvotes: 1

Rex Kerr
Rex Kerr

Reputation: 167891

If you don't tell it that the argument of A is of the right type, it will fill in an anonymous type parameter (the _$1 is an anonymous type used for the argument of A) and won't necessarily make it as specific as it needs to be . Just specify a valid type yourself instead:

class Question[T <: A[T]](root: A[T])

and the compiler will be happy.

Upvotes: 2

Related Questions