The following macro is pasted from http://docs.scala-lang.org/overviews/quasiquotes/usecases.html:
import reflect.macros.Context
import language.experimental.macros
val universe = reflect.runtime.universe; import universe._
import reflect.runtime.currentMirror
import tools.reflect.ToolBox
val toolbox = currentMirror.mkToolBox()
object debug {
def apply[T](x: =>T): T = macro impl
def impl(c: Context)(x: c.Tree) = { import c.universe._
val q"..$stats" = x
val loggedStats = stats.flatMap { stat =>
val msg = "executing " + showCode(stat)
List(q"println($msg)", stat)
}
q"..$loggedStats"
}
}
It produces this error message in Scala 2.11.1:
Q.scala:9: error: macro implementation reference has wrong shape. required:
macro [<static object>].<method name>[[<type args>]] or
macro [<macro bundle>].<method name>[[<type args>]]
def apply[T](x: =>T): T = macro impl
^
I've tried varying the code in numerous ways (import reflect.macros.whitebox.Context
, import reflect.macros.blackbox.Context
, putting scala.
at the start of each import, making the arguments consistently by-name or consistently by-value, macro impl[T]
, getting rid of the type parameter, macro debug.impl
, putting the apply
after the impl
, and more) with no success. What am I doing wrong? Is it something in the imports? Those come (mostly) from a different web page, http://docs.scala-lang.org/overviews/quasiquotes/setup.html.
The same error occurs on both of the other example macros from that page:
object Macro {
def apply(x: Int): Int = macro impl
def impl(c: Context)(x: c.Expr[Int]): c.Expr[Int] = { import c.universe._
c.Expr(q"$x + 1")
}
}
object Macro {
def apply(x: Int): Int = macro impl
def impl(c: Context)(x: c.Tree) = { import c.universe._
q"$x + 1"
}
}
scala Foo.scala
wraps the code that you feed to it in an anonymous class. As a result, something like:Gets transformed into:
However, macro implementations must be defined in static object or bundles, which is what the error messages tries to say:
Unfortunately, if something is put into inside an anonymous class, it's no longer static, which means that
scala Foo.scala
-style development is incompatible with macros. Consider using alternatives, e.g.scalac
orsbt
.