Cheetah
Cheetah

Reputation: 14379

Scala macro Liftable with forward reference

I very roughly have the following code:

object MyObj {
  def callWithParams(params: List[Param]): String = "some string"
}

sealed trait Param
case class Single(id: Int) extends Param
case class Group(id: Int, subParams: List[Param]) extends Param

def buildMyParams(): List[Param] = List(Single(1), Group(2, List(Group(3, Single(4))))

def macroImpl(c: blackbox.Context): c.Expr[String] = {
  import c.universe._

  // TODO: need a implicit Lift[Param] implementation here

  val myParams = buildMyParams()
  c.Expr[String](q"MyObj.callWithParams($myParams)")
}

My attempt at the implicit List[Param] is:

implicit val lift = Liftable[Param]({
  case s: Single => q"Single(${s.id})"
  case g: Group => q"Group(${g.id}, ${g.subParams})"
})

This doesn't compile because of the forward reference in the Liftable when trying to lift a Group, because of Group.subParams.

How do I get around this issue?

Upvotes: 2

Views: 135

Answers (1)

Cheetah
Cheetah

Reputation: 14379

Declaring the lift as a def rather than a val was enough to fix this:

implicit def lift = Liftable[Param]({
  case s: Single => q"Single(${s.id})"
  case g: Group => q"Group(${g.id}, ${g.subParams})"
})

Upvotes: 2

Related Questions