Search code examples
scalametaprogrammingimplicitscala-macros

Postpone implicit resolution until macro expansion


Consider trivial macro:

def test[A](a: A): Unit = macro testImpl[A]

def testImpl[A: c.WeakTypeTag](c: blackbox.Context)(a: c.Expr[A]): c.Expr[Unit] = {
  import c.universe._
  println("Test running")
  c.Expr[Unit](q"")
}

and its invocation

def foo(a: String)(implicit b: Int): Unit = ???

test(foo("123"))

It gives an error that

[error] Main.scala:19:18: could not find implicit value for parameter b: Int
[error]     test(foo("123"))

Is it possible to defer implicit resolution until macro expansion time or writing macro annotation is necessary for such cases?


Solution

  • On contrary to macro annotations annotating untyped annottees, parameters of a def macro are always typechecked before the macro is expanded. And typechecking includes implicit resolution.

    You can also try to make a parameter of def macro String

    test("""foo("123")""")
    

    (use c.parse in the definition of test).

    http://www.scala-archive.org/Expand-macros-before-typechecking-its-arguments-trees-td4641188.html

    Scala: macro to create an instance from a class body