0

My questions are:

  1. what is this warning about? There is no type parameter for reflect.runtime.universe.TypeRef
  2. why this is thrown on method invocation arg rather than asInstanceOf?

Console output:

Welcome to Scala version 2.10.0 (Java HotSpot(TM) Client VM, Java 1.6.0_35).
Type in expressions to have them evaluated.
Type :help for more information.

scala>  import reflect.runtime.{universe => ru}
import reflect.runtime.{universe=>ru}

scala>  val t = ru.typeOf[Option[_]]
t: reflect.runtime.universe.Type = scala.Option[_]

scala>  t.isInstanceOf[ru.TypeRef]
<console>:10: warning: abstract type reflect.runtime.universe.TypeRef is unchecked since it is eliminated by erasure
              t.isInstanceOf[ru.TypeRef]
                            ^
res0: Boolean = true

scala>  t.asInstanceOf[ru.TypeRef]
res1: reflect.runtime.universe.TypeRef = scala.Option[_]

scala>  t.asInstanceOf[ru.TypeRef].args
java.lang.ClassCastException: scala.reflect.internal.Types$ExistentialType cannot be cast to scala.reflect.api.Types$TypeRefApi
    at .<init>(<console>:10)
    at .<clinit>(<console>)
    at .<init>(<console>:7)
    at .<clinit>(<console>)
    at $print(<console>)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at scala.tools.nsc.interpreter.IMain$ReadEvalPrint.call(IMain.scala:731)
    at scala.tools.nsc.interpreter.IMain$Request.loadAndRun(IMain.scala:980)
    at scala.tools.nsc.interpreter.IMain.loadAndRunReq$1(IMain.scala:570)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:601)
    at scala.tools.nsc.interpreter.IMain.interpret(IMain.scala:565)
    at scala.tools.nsc.interpreter.ILoop.reallyInterpret$1(ILoop.scala:745)
    at scala.tools.nsc.interpreter.ILoop.interpretStartingWith(ILoop.scala:790)
    at scala.tools.nsc.interpreter.ILoop.command(ILoop.scala:702)
    at scala.tools.nsc.interpreter.ILoop.processLine$1(ILoop.scala:566)
    at scala.tools.nsc.interpreter.ILoop.innerLoop$1(ILoop.scala:573)
    at scala.tools.nsc.interpreter.ILoop.loop(ILoop.scala:576)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply$mcZ$sp(ILoop.scala:867)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
    at scala.tools.nsc.interpreter.ILoop$$anonfun$process$1.apply(ILoop.scala:822)
    at scala.tools.nsc.util.ScalaClassLoader$.savingContextLoader(ScalaClassLoader.scala:135)
    at scala.tools.nsc.interpreter.ILoop.process(ILoop.scala:822)
    at scala.tools.nsc.interpreter.ILoop.main(ILoop.scala:889)
    at org.jetbrains.plugins.scala.compiler.rt.ConsoleRunner.main(ConsoleRunner.java:64)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.application.AppMain.main(AppMain.java:120)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at com.intellij.rt.execution.CommandLineWrapper.main(CommandLineWrapper.java:121)
Max
  • 2,065
  • 24
  • 20

1 Answers1

3

TypeRef is an abstract type, therefore it's erased to its upper bound. Typically this means that it's impossible to do reliable isInstanceOf and pattern matching (which ultimately relies on that).

However since reflection API extensively uses abstract types, we built in a special mechanism to pattern match instances of abstract types, based on class tags. If in scope you have a class tag corresponding to the abstract type, everything works reliably.

Naturally, we provide a bunch of class tags bundled in universes, one per almost every abstract type. The catch is that you do need to import those class tags. Usually that's not a problem, because almost everyone does import ru._, but in cases like that it comes up. We recognize this as an issue, but it remains to be fixed.

Eugene Burmako
  • 13,028
  • 1
  • 46
  • 59