1

reify を使用する簡単なテスト マクロがあります。マクロ展開時に StackOverflowError が発生します。

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で試してみたところ、次のように表示されます

実装制限: 型 Object{def (): O.type} (ClassInfoType) を具体化できません

これで理由の質問に答えましたが、これを回避する方法があるかどうかという質問はまだ残っています。

4

2 に答える 2

3

現在、具体化者は、具体化されているブロック内で定義されたものを参照する型を具体化する方法を認識していません。したがって、エラー。

しかし、それはあなたの例と何の関係がありますか? 仕組みは次のとおりです。

コード ブロックを具体化するために、コンパイラはdef apply[T: AbsTypeTag](mirror: MirrorOf[self.type], treec: TreeCreator): Expr[T](upd. in 2.10.0-RC1 AbsTypeTaghas been renamed to WeakTypeTag) を使用して、式を具体化する Expr 型のオブジェクトを作成します。ただし、Expr のコントラクトには、reifee の型もキャプチャすることが暗示されているため、問題が発生します。

したがって、回避策が必要です。最も単純な方法Oは、スニペットの最後の行で具体化可能なものにキャストすることです (例: write ) 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]
})
于 2012-09-06T16:45:07.490 に答える
1

最近、同じ問題にぶつかりました。しかし、(コンパイル時に)「変数」を区別するために他のマクロ内でシングルトン型を使用したため、オブジェクト型をキャストする余裕がありませんでした。したがって、オブジェクトを具体化する必要がある場合は、マクロ内で次のことを実行して、Unit 値の代わりにオブジェクトを具体化して返すことができます。

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")))
  })
}
于 2012-10-15T16:08:51.393 に答える