Scala Programming Language
  1. Scala Programming Language
  2. SI-6937

(runtime.universe: api.Universe).typeTag[A] throws Error

    Details

      Description

      The following is a bit inconvenient when sharing code between macro impls and runtime (which would otherwise be nice via passing around an api.Universe):

      Welcome to Scala version 2.10.0 (Java HotSpot(TM) 64-Bit Server VM, Java 1.7.0_07).
      Type in expressions to have them evaluated.
      Type :help for more information.
      
      scala> import reflect._
      import reflect._
      
      scala> class A
      defined class A
      
      scala> runtime.universe: api.Universe
      res2: scala.reflect.api.Universe = scala.reflect.runtime.JavaUniverse@4ab944df
      
      scala> res2.typeTag[A]
      scala.reflect.internal.MissingRequirementError: object $line4.$read not found.
      	at scala.reflect.internal.MissingRequirementError$.signal(MissingRequirementError.scala:16)
      	at scala.reflect.internal.MissingRequirementError$.notFound(MissingRequirementError.scala:17)
      	at scala.reflect.internal.Mirrors$RootsBase.ensureModuleSymbol(Mirrors.scala:126)
      	at scala.reflect.internal.Mirrors$RootsBase.staticModule(Mirrors.scala:161)
      	at scala.reflect.internal.Mirrors$RootsBase.staticModule(Mirrors.scala:21)
      	at $typecreator1$1.apply(<console>:13)
      	at scala.reflect.api.TypeTags$TypeTag$.apply(TypeTags.scala:302)
      	at .<init>(<console>:13)
      	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:57)
      	at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
      	at java.lang.reflect.Method.invoke(Method.java:601)
      	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.MainGenericRunner.runTarget$1(MainGenericRunner.scala:83)
      	at scala.tools.nsc.MainGenericRunner.process(MainGenericRunner.scala:96)
      	at scala.tools.nsc.MainGenericRunner$.main(MainGenericRunner.scala:105)
      	at scala.tools.nsc.MainGenericRunner.main(MainGenericRunner.scala)
      
      
      scala> runtime.universe: api.JavaUniverse
      res4: scala.reflect.api.JavaUniverse = scala.reflect.runtime.JavaUniverse@4ab944df
      
      scala> res4.typeTag[A]
      res5: res4.TypeTag[A] = TypeTag[A]
      

        Activity

        Hide
        Eugene Burmako added a comment -

        The problem lies here: https://github.com/scalamacros/kepler/blob/00fcd46ed0ed3e981e241c8b5458ba821294c669/src/reflect/scala/reflect/api/TypeTags.scala#L224.

        Type tag factory evaluates the provided type creator in the context of the initial mirror in order to maintain referential equality of instances of standard tags. Unfortunately this evaluation might fail if the mirror provided doesn't contain the classes being referred to. Therefore I think we should avoid evaluating type creators there.

        Note that failure of evaluation doesn't mean that there's something bad going on. When one creates a type tag, the correct mirror / classloader to interpret that tag in might be unknown (like it happens here). This is okay, and this is exactly what the 2.10.0-M4 refactoring has addressed. Something like `res2.typeTag[A].in(currentMirror)` is the correct response here.

        Show
        Eugene Burmako added a comment - The problem lies here: https://github.com/scalamacros/kepler/blob/00fcd46ed0ed3e981e241c8b5458ba821294c669/src/reflect/scala/reflect/api/TypeTags.scala#L224 . Type tag factory evaluates the provided type creator in the context of the initial mirror in order to maintain referential equality of instances of standard tags. Unfortunately this evaluation might fail if the mirror provided doesn't contain the classes being referred to. Therefore I think we should avoid evaluating type creators there. Note that failure of evaluation doesn't mean that there's something bad going on. When one creates a type tag, the correct mirror / classloader to interpret that tag in might be unknown (like it happens here). This is okay, and this is exactly what the 2.10.0-M4 refactoring has addressed. Something like `res2.typeTag [A] .in(currentMirror)` is the correct response here.
        Show
        Eugene Burmako added a comment - https://github.com/scala/scala/pull/2349

          People

          • Assignee:
            Eugene Burmako
            Reporter:
            Roland Kuhn
          • Votes:
            0 Vote for this issue
            Watchers:
            3 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development