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

Macro users are effectively required to have scala-reflect.jar on library classpath

    Details

    • Type: Bug Bug
    • Status: Closed
    • Priority: Critical Critical
    • Resolution: Fixed
    • Affects Version/s: Scala 2.10.0
    • Fix Version/s: Scala 2.10.0-M6
    • Component/s: Macros
    • Labels:
      None

      Description

      import scala.reflect.macros.Context
      
      object Macros {
        def impl(c: Context) = c.literalUnit
      
        def foo = macro impl
      }
      
      object Test extends App {
        Macros.foo
      }
      
      C:\Projects\Kepler\sandbox>java -cp c:/Projects/Kepler/build/asm/classes;c:/Projects/Kepler/build/locker/classes/library/;c:/Projects/Kepler/build/locker/classes/reflect/;c:/Projects/Kepler/build/locker/classes/compiler/ scala.tools.nsc.Main -language:experimental.macros -cp c:/Projects/Kepler/build/locker/classes/library;c:/Projects/Kepler/build/locker/classes/reflect Macros_1.scala
      
      
      C:\Projects\Kepler\sandbox>java -cp c:/Projects/Kepler/build/asm/classes;c:/Projects/Kepler/build/locker/classes/library/;c:/Projects/Kepler/build/locker/classes/reflect/;c:/Projects/Kepler/build/locker/classes/compiler/ scala.tools.nsc.Main -language:experimental.macros -cp c:/Projects/Kepler/build/locker/classes/library;. Test_2.scala
      error: error while loading Macros, Missing dependency 'bad reference while unpickling .\Macros.class: type Aliases not found in scala.reflect.makro.type', required by .\Macros.class
      Test_2.scala:2: error: macro implementation not found: foo (the most common reason for that is that you cannot use macro implementations in the same compilation run that defines them)
      if you do need to define macro implementations along with the rest of your program, consider two-phase compilation with -Xmacro-fallback-classpath in the second phase pointing to the output of the first phase
        Macros.foo
               ^
      two errors found
      
      C:\Projects\Kepler\sandbox>java -cp c:/Projects/Kepler/lib/fjbg.jar;c:/Projects/Kepler/build/locker/classes/library/;c:/Projects/Kepler/build/locker/classes/reflect/;c:/Projects/Kepler/build/locker/classes/compiler/ scala.tools.nsc.Main -language:experimental.macros -cp c:/Projects/Kepler/build/locker/classes/library;c:/Projects/Kepler/build/locker/classes/reflect;. Test_2.scala
      <java has exited with code 0>
      

        Activity

        Hide
        Eugene Burmako added a comment -

        This problem is caused by the fact that macros must be present on the library classpath to be used. Everything that's on the library classpath gets unpickled by scalac. Macro definitions are linked to their implementations via a macroImpl annotation. Hence even if a macro implementation itself isn't on the library classpath, its signature will be unpickled.

        Here comes the problem. In the current design, a signature of a macro implementation must declare a parameter of type scala.reflect.makro.Context, which belongs to scala-reflect.jar. This means that if scala-reflect.jar isn't present on the library classpath, unpickling will fail producing the aforementioned crash.

        Show
        Eugene Burmako added a comment - This problem is caused by the fact that macros must be present on the library classpath to be used. Everything that's on the library classpath gets unpickled by scalac. Macro definitions are linked to their implementations via a macroImpl annotation. Hence even if a macro implementation itself isn't on the library classpath, its signature will be unpickled. Here comes the problem. In the current design, a signature of a macro implementation must declare a parameter of type scala.reflect.makro.Context, which belongs to scala-reflect.jar. This means that if scala-reflect.jar isn't present on the library classpath, unpickling will fail producing the aforementioned crash.
        Hide
        Eugene Burmako added a comment - - edited

        To be honest, I don't have much hope about fixing this by 2.10.0-final.

        An attempt to factor out lite context and put it into scala-library.jar has officially failed: https://github.com/scalamacros/kepler/tree/zzz/basecontext. It not only requires one to cast a lite context to a full-fledged one, but also necessitates casts for arguments and return value of the macro implementation. We could live with a little tiny cast in the beginning of a macro, but even more boilerplate can't be tolerated.

        Therefore I'm demoting this issue from critical to major, effectively deferring the fix till 2.10.1 or later, when macros upgrade from their experimental status and join the family of stable Scala features.

        By no means I consider this bug not important. Imposing the scala-reflect.jar requirement on macro users (not macro authors, but macro users!!) is horrific, but to quote a really nice observation "this is a marathon, not a sprint".

        Show
        Eugene Burmako added a comment - - edited To be honest, I don't have much hope about fixing this by 2.10.0-final. An attempt to factor out lite context and put it into scala-library.jar has officially failed: https://github.com/scalamacros/kepler/tree/zzz/basecontext . It not only requires one to cast a lite context to a full-fledged one, but also necessitates casts for arguments and return value of the macro implementation. We could live with a little tiny cast in the beginning of a macro, but even more boilerplate can't be tolerated. Therefore I'm demoting this issue from critical to major, effectively deferring the fix till 2.10.1 or later, when macros upgrade from their experimental status and join the family of stable Scala features. By no means I consider this bug not important. Imposing the scala-reflect.jar requirement on macro users (not macro authors, but macro users!!) is horrific, but to quote a really nice observation "this is a marathon, not a sprint".
        Hide
        Daniel Sobral added a comment -

        But this is only at compile time, right? When you compile the macro, and when you compile something else that uses the macro. When that something is is run, there's no need for scala-reflect.jar anymore, is there?

        Show
        Daniel Sobral added a comment - But this is only at compile time , right? When you compile the macro, and when you compile something else that uses the macro. When that something is is run , there's no need for scala-reflect.jar anymore, is there?
        Hide
        Eugene Burmako added a comment -

        True. The dependency is purely compile-time.

        Show
        Eugene Burmako added a comment - True. The dependency is purely compile-time.
        Show
        Eugene Burmako added a comment - Discussion: http://groups.google.com/group/scala-internals/browse_thread/thread/fb7d6af7f9f0fcc6
        Hide
        Eugene Burmako added a comment -

        Back to critical after a discussion on scala-internals

        Show
        Eugene Burmako added a comment - Back to critical after a discussion on scala-internals
        Show
        Eugene Burmako added a comment - https://github.com/scala/scala/pull/1101
        Show
        Eugene Burmako added a comment - https://github.com/scala/scala/commit/64138082a4f1bb4c864d85660d350f61c81e7fd7

          People

          • Assignee:
            Eugene Burmako
            Reporter:
            Eugene Burmako
          • Votes:
            0 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:

              Development