5

我如何解决两个我知道是相同但编译器不一样的路径相关类型的等价?

使用 Scala 2.10.0 M7 我正在尝试将 AST 从一个宇宙转换为另一个。

case class MacroBridge(context: Context) {
  def toMacroTree(tree: treehugger.forest.Tree): context.universe.Tree = ???
  def fromMacroTree(tree: context.universe.Tree): treehugger.forest.Tree = ???
}

在宏实现中,我可以将其用作:

val bridge = treehugger.MacroBridge(c)
def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree)

但是,这会导致编译器错误:

[error] /scalamacros-getting-started/library/Macros.scala:21: type mismatch;
[error]  found   : c.universe.Tree
[error]  required: bridge.context.universe.Tree
[error]  possible cause: missing arguments for method or constructor
[error]     def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree)

上面代码c中的值显然与 相同bridge.context,但可能是因为它是一个值类型检查器,无法检查它。放置广义类型约束没有帮助:

def fromMacroTree[A](tree: A)(implicit ev: A =:= context.universe.Tree): Tree =

在宏中,这仍然导致错误:

[error] /scalamacros-getting-started/library/Macros.scala:21: Cannot prove that c.universe.Tree =:= bridge.context.universe.Tree.
[error]     def fromMacroTree(tree: c.universe.Tree): Tree = bridge.fromMacroTree(tree)

我需要访问权限,context.universe以便可以访问其他依赖类型,例如TermName. 除了铸造之外还有更好的解决方法吗?

def fromMacroTree(tree: c.universe.Tree): Tree =
  bridge.fromMacroTree(tree.asInstanceOf[bridge.context.universe.Tree])
4

1 回答 1

9

我可以使以下工作:

case class MacroBridge[C <: Context](context: C) {
  def fromMacroTree(tree: context.universe.Tree): context.universe.Tree = ???
}

trait MB {
  def meth(c: Context) {
    val bridge = MacroBridge[c.type](c)
    def fromMacroTree(tree: c.universe.Tree): c.universe.Tree =
      bridge.fromMacroTree(tree)
  }
}

前段时间我遇到了几乎同样的问题。

于 2012-08-26T23:48:37.933 回答