如何删除宏中所有推断的隐式?
How to remove all inferred implicits in a macro?
我需要真的取消对我的宏发出的树的类型检查。这意味着不仅要删除推断类型等等,还要删除编译器推断的隐式参数。甚至 resetAllAttrs
似乎都没有解决这个问题。
Symbol
s 似乎有一个方法 isSynthetic
指示代码是否由编译器生成,但显然该标志仅针对自动生成的 getter 和 setter 之类的东西设置,而不是针对隐式值编译器插入。
我当然可以手动查找所有隐式参数列表并删除它们,但我也会删除那些由我的宏的用户明确提供的列表。
下面的代码非常理想
scala> def foo(a: Int)(implicit e: DummyImplicit) = a
foo: (a: Int)(implicit e: DummyImplicit)Int
scala> myMacro{ foo(4); foo(2)(DummyImplicit.dummyImplicit) }
myMacro
会发出树
{
foo(4);
foo(2)(Predef.this.DummyImplicit.dummyImplicit)
}
然后再次进行类型检查并编译。
但是这恐怕做不到...
他们有 internal API 来检测隐式提供的参数,但它被评论为不稳定。 (他们将使用树附件而不是 Apply 的子类型。)
$ scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.
scala> import language.experimental.macros
import language.experimental.macros
scala> import reflect.macros.blackbox.Context
import reflect.macros.blackbox.Context
scala> def fImpl(c: Context)(block: c.Expr[Any]): c.Expr[Boolean] = c.Expr { import c._, universe._
| val trees = universe.asInstanceOf[reflect.internal.Trees]
| block.tree match {
| case t@Apply(_,_) => Literal(Constant(t.isInstanceOf[trees.ApplyToImplicitArgs]))
| case _ => Literal(Constant(false)) }}
fImpl: (c: scala.reflect.macros.blackbox.Context)(block: c.Expr[Any])c.Expr[Boolean]
scala> def f(block: Any): Boolean = macro fImpl
defined term macro f: (block: Any)Boolean
scala> def g(implicit d: DummyImplicit) = 42
g: (implicit d: DummyImplicit)Int
scala> f(println(""))
res0: Boolean = false
scala> f(g)
res1: Boolean = true
scala> f(g(new DummyImplicit))
res2: Boolean = false
我需要真的取消对我的宏发出的树的类型检查。这意味着不仅要删除推断类型等等,还要删除编译器推断的隐式参数。甚至 resetAllAttrs
似乎都没有解决这个问题。
Symbol
s 似乎有一个方法 isSynthetic
指示代码是否由编译器生成,但显然该标志仅针对自动生成的 getter 和 setter 之类的东西设置,而不是针对隐式值编译器插入。
我当然可以手动查找所有隐式参数列表并删除它们,但我也会删除那些由我的宏的用户明确提供的列表。
下面的代码非常理想
scala> def foo(a: Int)(implicit e: DummyImplicit) = a
foo: (a: Int)(implicit e: DummyImplicit)Int
scala> myMacro{ foo(4); foo(2)(DummyImplicit.dummyImplicit) }
myMacro
会发出树
{
foo(4);
foo(2)(Predef.this.DummyImplicit.dummyImplicit)
}
然后再次进行类型检查并编译。
但是这恐怕做不到...
他们有 internal API 来检测隐式提供的参数,但它被评论为不稳定。 (他们将使用树附件而不是 Apply 的子类型。)
$ scala
Welcome to Scala 2.12.1 (Java HotSpot(TM) 64-Bit Server VM, Java 1.8.0_111).
Type in expressions for evaluation. Or try :help.
scala> import language.experimental.macros
import language.experimental.macros
scala> import reflect.macros.blackbox.Context
import reflect.macros.blackbox.Context
scala> def fImpl(c: Context)(block: c.Expr[Any]): c.Expr[Boolean] = c.Expr { import c._, universe._
| val trees = universe.asInstanceOf[reflect.internal.Trees]
| block.tree match {
| case t@Apply(_,_) => Literal(Constant(t.isInstanceOf[trees.ApplyToImplicitArgs]))
| case _ => Literal(Constant(false)) }}
fImpl: (c: scala.reflect.macros.blackbox.Context)(block: c.Expr[Any])c.Expr[Boolean]
scala> def f(block: Any): Boolean = macro fImpl
defined term macro f: (block: Any)Boolean
scala> def g(implicit d: DummyImplicit) = 42
g: (implicit d: DummyImplicit)Int
scala> f(println(""))
res0: Boolean = false
scala> f(g)
res1: Boolean = true
scala> f(g(new DummyImplicit))
res2: Boolean = false