Main:
import scala.quoted.{Expr, Quotes, Type}
trait CustomTag[A]
class MyClass[A] {
def add[B](mc2: MyClass[B])(using CustomTag[B]) = ???
}
object Macros {
inline def myMacro(inline lhs: MyClass[_], inline rhs: MyClass[_]): Unit =
${ myMacroImpl('lhs, 'rhs) }
def myMacroImpl(lhs: Expr[MyClass[_]], rhs: Expr[MyClass[_]])(using Quotes): Expr[Unit] = {
val l3 = lhs match {
case '{ $lhs: MyClass[i] } =>
rhs match {
case '{ $rhs: MyClass[i2] } =>
'{ $lhs.add($rhs) }
// Expr.summon[CustomTag[i2]] match {
// case Some(t) => '{ $lhs.add($rhs)(using $t) }
// case None => ???
// }
}
}
'{$l3; ()}
}
implicit transparent inline def materialize[A]: CustomTag[A] =
${ materializeImpl[A] }
def materializeImpl[A: Type](using Quotes): Expr[CustomTag[A]] = {
???
}
}
Test:
import Macros._
def test[MyC: CustomTag]() = {
val m1 = MyClass[String]()
val m2 = MyClass[MyC]()
val o = Macros.myMacro(m1, m2)
}
@main
def main() = {
}
When calling $lhs.add($rhs)
implicit that is actually found is not one from MyC: CustomTag
, but is from implicit def. I would expect macro to find implicit that is in it’s closest scope, not the global one. To use implicit that is in macro’s scope I have to use Expr.summon[CustomTag]
and explicitly pass it to method invocation, is it by design?