0
votes

I have a trait T, I implement it with macro in class C. i create an instance of C and invoke its methods. if the type of the val containing an instance of C is C - works as expected. if the type of the val containing an instance of C is T - invokes methods as if T.

best way to describe it that i can come up with is "virtual table broken" in scala-macros, but i don't know if that's a thing...

example code:

Type in expressions for evaluation. Or try :help.

scala>

scala>

scala> import language.experimental.macros
import language.experimental.macros

scala>

scala>

scala> trait T { def doSomething(): Unit = println ("trait") }
defined trait T

scala>

scala>

scala> import scala.reflect.macros.Context
import scala.reflect.macros.Context

scala>

scala>

scala> object Macro {
     |   def doSomething(c: Context)(): c.universe.Tree = {
     |     import c.universe._
     |     q"""println ("macro")"""
     |   }
     | }
warning: there was one deprecation warning (since 2.11.0); for details, enable `:setting -deprecation' or `:replay -deprecation'
defined object Macro

scala>

scala>

scala> class C extends T { override def doSomething(): Unit = macro Macro.doSomething }
defined class C

scala>

scala> val c: C = new C()
c: C = C@3bd1883a

scala> c.doSomething()
macro

scala>

scala> val t: T = new C()
t: T = C@4079fec7

scala> t.doSomething()
trait
1
my actual use case is contributing a PR to scala-logging, i want a base trait "ALogger" to be implemented by 2 different macro implementations, and want consumers of the logger to be able to say abstractly that they have ALogger, but for the logger to be determined later via Mixin or inheritance. github.com/lightbend/scala-logging/pull/212nathan g

1 Answers

1
votes

Def macros are expanded at compile time so late binding / dynamic dispatch (which is a runtime feature) is impossible for them.

At compile time it's unknown that t has type C, at compile time it's only known that t has type T.

See details here: Eugene Burmako. Unification of Compile-Time and Runtime Metaprogramming in Scala https://infoscience.epfl.ch/record/226166/files/EPFL_TH7159.pdf p. 98, §4.6.1 "Inheritance"