Scala macro: rewrite partial function into match -
i rewrite partial function
match
expression.
//macro , impl def pfrewrite(pf: partialfunction[int, int]) = macro responderimpl.pfrewriteimpl def pfrewriteimpl(c: context)(pf: c.expr[partialfunction[int, int]]) = { import c.universe._ val cas = pf.tree.collect { case x: defdef if x.name.decoded == "applyorelse" => x.collect { case cq"$x => $y" => cq"""$x => $y""" } }.flatten val sval = newtermname("someval") val rewrite = q""" $sval match { case ..$cas } """ c.expr(rewrite) }
in code got partialfunction
, take cases
applyorelse
method, next create match
expression "someval". value code:
//test def test { val someval = 10 pfrewrite { case 1 => 10 case _ => 100 } }
but got errors:
[error] found : int(10) [error] required: nothing [error] case 1 => 10 [error] ^
and etc.
it possible rewrite partial function call match ?
typically these kinds of awkward error messages stem mixing typed , untyped trees (for more details take @ scala macros: difference between typed (aka typechecked) untyped trees). therefore, until we've fixed situation, it's practice resetlocalattrs on typed trees plan mix untyped ones.
this case not exception. using c.resetlocalattrs(pf.tree)
instead of pf.tree
reveals real problem macro expansion:
12:57 ~/projects/master/sandbox (master)$ scalac test.scala test.scala:5: error: not found: value default macros.pfrewrite { ^
if enable -xprint:typer
, 1 of ways see macro expansions (along -ymacro-debug-lite
, -ymacro-debug-verbose
), we'll see what's going on:
[[syntax trees @ end of typer]] // test.scala package <empty> { object test extends anyref app { def <init>(): test.type = { test.super.<init>(); () }; def test: unit = { val someval: int = 10; { someval match { case 1 => 10 case _ => 100 case (defaultcase$ @ _) => <default: error>.apply(<x1: error>) }; () } } } }
it looks partial function synthesis adds default case can't reuse as-is, refers synthetic variables defined in synthesized class.
Comments
Post a Comment