jedesah
jedesah

Reputation: 3013

Compiler crash in simple macro manipulating a match statement

def control(x: String): Option[String] = macro controlImpl
def controlImpl(c: Context)(x: c.Expr[String]): c.Expr[Option[String]] = {
    import c.universe._
    val result = x.tree match {
        case Match(expr, cases) =>
            val matchz = Match(q"""List("hello")""", cases)
            q"Some(List(5)).map{a => $matchz}"
        case a => a
    }
    c.Expr[Option[String]](result)
}

This macro crashes during macro expansion with the following error:

java.lang.IllegalArgumentException: Could not find proxy for val o7: Some in List(value o7, method apply, <$anon: Function1>, value f, method apply, <$anon: Function1>, method apply, <$anon: Function0>, value <local ApplicativeTest>, object ApplicativeTest, package scalaz, package <root>) (currentOwner= value one )

This is the macro application point:

val f = IdiomBracket.control {
    a.get match {
        case List(one) => one
        case _ => ""
    }
}

What is odd is that if you substitute q"Some(List(5)).map{a => $matchz}" with q"Some($matchz)" then the compiler crash goes away.

Upvotes: 1

Views: 252

Answers (1)

som-snytt
som-snytt

Reputation: 39577

"Simple macro" is an oxymoron.

The crash is in lambda lift, which indicates a bad symbol owner.

You can inspect the tree you produce with -Ybrowse:typer.

Consider what you'd like to produce:

class X {
  //def g = List("hello") match { case List(x) => x case _ => "" }
  def f = Some(List(5)).map{a => List("hello") match { case List(x) => x case _ => "" } }
}

The var in the case is owned by the anonfun you want to create:

Symbol: [has] value x
Symbol owner: value $anonfun

Your actual result:

Symbol: [has] value x
Symbol owner: value <local Controlled>

where Controlled is my sample enclosing object for your code.

You might have to rebuild the cases, as opposed to just cases map (_.untypecheck).

https://github.com/scala/scala/blob/v2.11.5/src/reflect/scala/reflect/api/Trees.scala#L1100

Upvotes: 2

Related Questions