Scala 具体化宏扩展期间的StackOverflower错误

Scala 具体化宏扩展期间的StackOverflower错误,scala,macros,scala-2.10,reification,reify,Scala,Macros,Scala 2.10,Reification,Reify,我有一个使用具体化的简单测试宏。它会在宏扩展期间导致StackOverflower错误 def test() = macro testimpl def testimpl(c:Context)():c.Expr[Any] = { import c.universe._ val o = reify { // StackOverflowError here object O O } o } 为什么会发生这种情况?它能以某种方式避免吗 编辑:这就是M6的情况。我刚用M

我有一个使用具体化的简单测试宏。它会在宏扩展期间导致StackOverflower错误

def test() = macro testimpl

def testimpl(c:Context)():c.Expr[Any] = {
  import c.universe._
  val o = reify { // StackOverflowError here
    object O
    O
  }
  o
}
为什么会发生这种情况?它能以某种方式避免吗

编辑:这就是M6的情况。我刚用M7试过,现在它说

实现限制:无法具体化类型对象{def():O.type}(ClassInfo类型)


这就回答了为什么的问题,但问题仍然是是否有办法解决这个问题。

目前,具体化者不知道如何具体化引用被具体化块中定义的内容的类型。因此出现了错误

但是这和你的例子有什么关系呢?下面是它的工作原理

为了具体化代码块,编译器使用
def apply[T:AbsTypeTag](mirror:MirrorOf[self.type],treec:TreeCreator):Expr[T]
(upd.in 2.10.0-RC1
AbsTypeTag
已重命名为
WeakTypeTag
)创建一个具体化表达式的Expr类型的对象。然而,Expr合同中隐含的一点是,它还捕获了reifee的类型,这就产生了问题

因此,您需要一个变通方法。最简单的方法是将代码段最后一行中的
O
转换为可修改的内容,例如编写
O.asInstanceOf[Object]
。然后,您可以手动从结果中删除
asInstanceOf
零件

scala> reify { object O; O }
<console>:26: error: implementation restriction: cannot reify type Object{def <init>(): O.type} (ClassInfoType)
              reify { object O; O }
                    ^

scala> reify { object O; O.asInstanceOf[Object] }
res1 @ 2d059fd6: reflect.runtime.universe.Expr[Object] =
Expr[java.lang.Object]({
  object O extends AnyRef {
    def <init>() = {
      super.<init>();
      ()
    }
  };
  O.asInstanceOf[Object]
})
scala>具体化{object O;O}
:26:错误:实现限制:无法具体化类型对象{def():O.type}(ClassInfo类型)
具体化{object O;O}
^
scala>具体化{object O;O.asInstanceOf[object]}
res1@2d059fd6:reflect.runtime.universe.Expr[Object]=
Expr[java.lang.Object]({
对象O扩展AnyRef{
def()={
超级(;
()
}
};
O.a安装[对象]
})

目前,具体化者不知道如何具体化引用正在具体化的块中定义的内容的类型。因此出现了错误

但是这和你的例子有什么关系呢?下面是它的工作原理

为了具体化代码块,编译器使用
def apply[T:AbsTypeTag](mirror:MirrorOf[self.type],treec:TreeCreator):Expr[T]
(upd.in 2.10.0-RC1
AbsTypeTag
已重命名为
WeakTypeTag
)创建一个具体化表达式的Expr类型的对象。然而,Expr合同中隐含的一点是,它还捕获了reifee的类型,这就产生了问题

因此,您需要一个变通方法。最简单的方法是将代码段最后一行中的
O
转换为可修改的内容,例如编写
O.asInstanceOf[Object]
。然后,您可以手动从结果中删除
asInstanceOf
零件

scala> reify { object O; O }
<console>:26: error: implementation restriction: cannot reify type Object{def <init>(): O.type} (ClassInfoType)
              reify { object O; O }
                    ^

scala> reify { object O; O.asInstanceOf[Object] }
res1 @ 2d059fd6: reflect.runtime.universe.Expr[Object] =
Expr[java.lang.Object]({
  object O extends AnyRef {
    def <init>() = {
      super.<init>();
      ()
    }
  };
  O.asInstanceOf[Object]
})
scala>具体化{object O;O}
:26:错误:实现限制:无法具体化类型对象{def():O.type}(ClassInfo类型)
具体化{object O;O}
^
scala>具体化{object O;O.asInstanceOf[object]}
res1@2d059fd6:reflect.runtime.universe.Expr[Object]=
Expr[java.lang.Object]({
对象O扩展AnyRef{
def()={
超级(;
()
}
};
O.a安装[对象]
})

我最近碰到了同样的问题。但是我不能强制转换对象类型,因为我在另一个宏中使用了singleton类型来区分(编译时)“变量”。因此,如果确实需要具体化对象,可以在宏中执行以下操作,以便具体化返回对象而不是单位值

def mkObject(c: Context) = {
  import c.universe._

  val objectO = reify { object O }
  c.Expr(objectO.tree match {
    case Block(stats, expr) => Block(stats, Ident(newTermName("O")))
  })
}

我最近碰到了同样的问题。但是我不能强制转换对象类型,因为我在另一个宏中使用了singleton类型来区分(编译时)“变量”。因此,如果确实需要具体化对象,可以在宏中执行以下操作,以便具体化返回对象而不是单位值

def mkObject(c: Context) = {
  import c.universe._

  val objectO = reify { object O }
  c.Expr(objectO.tree match {
    case Block(stats, expr) => Block(stats, Ident(newTermName("O")))
  })
}