I need to search for an implicit value at a given position. I retained the position from a previous macro call in a class, like so :
class Delayed[+Kind[_[_]]](val sourceFilePath: String, val callSitePoint: Int) {
def find[F[_]]: Kind[F] = macro Impl.find[Kind, F]
}
The previous macro is very simple :
def build[Kind[_[_]]](c: blackbox.Context): c.Expr[Delayed[Kind]] = {
import c.universe._
c.Expr(
q"""
new Delayed(${c.enclosingPosition.point}, ${c.enclosingPosition.source.path})
"""
)
}
With this I have the position, all I need to do is to launch the implicit search right ?
def find[Kind[_[_]], F[_]](c: blackbox.Context)(implicit kindTag: c.WeakTypeTag[Kind[F]], fTag: c.WeakTypeTag[F[_]]): c.Expr[Kind[F]] = {
import c.universe._
reify {
val self = c.prefix.splice.asInstanceOf[Delayed[Kind]]
val sourceFile = AbstractFile.getFile(self.sourceFilePath)
val batchSourceFile = new BatchSourceFile(sourceFile, sourceFile.toCharArray)
val implicitSearchPosition = new OffsetPosition(batchSourceFile, self.callSitePoint).asInstanceOf[c.Position]
c.Expr[Kind[F]](c.inferImplicitValue(
appliedType(kindTag.tpe.typeConstructor, fTag.tpe.typeConstructor),
pos = implicitSearchPosition
)).splice
}
}
I get the position using reify/splice calls and then apply inferImplicitValue
. But the compiler complains about the last splice on the implicit value :
the splice cannot be resolved statically,
which means there is a cross-stage evaluation involved
It asks me to add the compiler jar as dependencies, but by doing so I only get another error :
Macro expansion contains free term variable c defined by find in Delayed.scala
I understand that reify is, conceptually, in the world of values. What I don't understand is that the implicit search should be resolved before the macro-generated code is written to my source code. That the only way I can think of for the implicit search to work in macro contexts.
Where I am wrong ? I do understand the compiler messages, but to me, it makes no sense in this particular context. Maybe I don't get how inferImplicitValue
works.
Try Context#eval(expr)
def find[Kind[_[_]], F[_]](c: blackbox.Context)(implicit kindTag: c.WeakTypeTag[Kind[F]], fTag: c.WeakTypeTag[F[_]]): c.Expr[Kind[F]] = {
import c.universe._
val self = c.eval(c.Expr[Delayed[Kind]](c.untypecheck(c.prefix.tree.duplicate)))
val sourceFile = AbstractFile.getFile(self.sourceFilePath)
val batchSourceFile = new BatchSourceFile(sourceFile, sourceFile.toCharArray)
val implicitSearchPosition = new OffsetPosition(batchSourceFile, self.callSitePoint).asInstanceOf[c.Position]
c.Expr[Kind[F]](c.inferImplicitValue(
appliedType(kindTag.tpe.typeConstructor, fTag.tpe.typeConstructor),
pos = implicitSearchPosition
))
}
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.