scalamacros / paradise

(No longer actively maintained.)
http://scalamacros.org/
BSD 3-Clause "New" or "Revised" License
158 stars 53 forks source link

Illegal cyclic reference in 2.12 when typechecking in macro #100

Open cornerman opened 7 years ago

cornerman commented 7 years ago

I have a macro annotation with paradise, which typechecks an annotated ValDef. It compiles in scala 2.11.11, but gives an illegal cyclic reference error in 2.12.2. I am not sure whether this a scala bug or because of paradise. A short example:

import scala.reflect.macros.whitebox.Context
import scala.language.experimental.macros
import scala.annotation.{StaticAnnotation, compileTimeOnly}

object Macro {
  def impl(c: Context)(annottees: c.Expr[Any]*): c.Expr[Any] = {
    import c.universe._

    annottees.map(_.tree) match {
      case (valDef: ValDef) :: _ =>

        //this works in scala 2.11.11 and 2.12.2
        c.typecheck(valDef, withMacrosDisabled = true)

        //this works in scala 2.11.11, but not in 2.12.2
        val unmodValDef = ValDef(Modifiers(), valDef.name, valDef.tpt, valDef.rhs)
        c.typecheck(unmodValDef, withMacrosDisabled = true)

        annottees.head
      case _ => c.abort(c.enclosingPosition, "unsupported annotation")
    }
  }
}

@compileTimeOnly("only for compile time expansion")
class example extends StaticAnnotation {
  def macroTransform(annottees: Any*): Any = macro Macro.impl
}

Using this annotation on a val:

// using a trait instead of a class compiles in 2.12.2
class Wrap {
  @example val x: Int = 1
}

In 2.12.2, this leads to an illegal cyclic reference error:

[error] [0] /scala/ExampleSpec.scala:7: illegal cyclic reference involving class Wrap

This is the failing code:

val unmodValDef = ValDef(Modifiers(), valDef.name, valDef.tpt, valDef.rhs)
//this works in scala 2.11.11, but not in 2.12.2
c.typecheck(unmodValDef, withMacrosDisabled = true)

An example project with repro.