I have an implicit macro that produces a class
trait Generated[T] {
def xxx:String
}
object M {
implicit def gen[T]:Generated[T] = macro MI.genImpl[T]
}
import scala.reflect.macros.blackbox.Context
import scala.language.experimental.macros
class MI(val c: Context) {
def genImpl[T: c.WeakTypeTag]: c.Tree = { ... }
}
and a class that uses this macro:
class MacroUser[T](par1:String)(implicit g:Generated[T]) {}
When I try to use that class and put it inside trait or object all is well
package bar
import M._
case class T(dummy:Int)
//this works - macro is called
trait Wrap {
class ConcreteUser1[T] extends MacroUser[T]("t")
}
//this does not work - implicit is not found, macro not called
class ConcreteUser2[T] extends MacroUser[T]("t")
Is it expected implicit macro behaviour ?
I’ve seen similar question Strange behaviour when implicit Macro used but also without answer
package foo
class
hmf
August 10, 2018, 8:59am
2
Just s suggestion for a test: have you tried making genImpl
a simple function and
have it use the (val c: Context)
parameter directly?
Also have you tried making MI
a case class or provide a companion object with
the appropriate apply
?
HTHs
I didn’t try any of the approaches yet - I’ll try that later on.
I tried putting gen explicitly and it is fine
class ConcreteUser2[T] extends MacroUser[T]("t")(gen[T])
works
actual (non shortened) code is in
package me.sgrouples.rogue.cc
import me.sgrouples.rogue.map.{ MapKeyFormat, MapKeyFormats }
import org.bson.types.ObjectId
import scala.language.experimental.{ macros => ms }
package object macros {
implicit def gen[T]: MacroBsonFormat[T] = macro MacroCCGenerator.genImpl[T]
implicit val StringMapKeyFormat = MapKeyFormats.StringMapKeyFormat
implicit val LongMapKeyFormat = MapKeyFormats.LongMapKeyFormat
implicit val IntMapKeyFormat = MapKeyFormats.IntMapKeyFormat
implicit val ObjectIdMapKeyFormat = MapKeyFormats.ObjectIdMapKeyFormat
implicit def objectIdSubtypeMapKeyFormat[S <: ObjectId]: MapKeyFormat[S] = MapKeyFormats.objectIdSubtypeMapKeyFormat[S]
}
and here
@f val int_named = IntField("int_custom_name")
}
trait TestQueryTraitB[OwnerType] {
requires: OwnerType with QueryFieldHelpers[OwnerType] =>
@f val optInt = OptIntField
@f val optInt_named = OptIntField("optInt_custom_name")
}
trait X {
class TestDomainObjectMeta extends MCcMeta[TestDomainObject, TestDomainObjectMeta]("abc")
with TestQueryTraitA[TestDomainObjectMeta]
with TestQueryTraitB[TestDomainObjectMeta] {
@f val claims = ListField[String]
@f val string = StringField
@f val string_named = StringField("string_custom_name")
I added X
trait to just avoid the problem.