Skip to content

Commit

Permalink
Expr.betaReduce support for polymorphic function
Browse files Browse the repository at this point in the history
Fixes #15968
  • Loading branch information
nicolasstucki committed Jan 9, 2023
1 parent e02c9e1 commit 7e4fe17
Show file tree
Hide file tree
Showing 3 changed files with 22 additions and 1 deletion.
5 changes: 4 additions & 1 deletion compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala
Original file line number Diff line number Diff line change
Expand Up @@ -362,11 +362,14 @@ class QuotesImpl private (using val ctx: Context) extends Quotes, QuoteUnpickler
object Term extends TermModule:
def betaReduce(tree: Term): Option[Term] =
tree match
// TODO support TypeApply. Would fix #15968.
case app @ tpd.Apply(tpd.Select(fn, nme.apply), args) if dotc.core.Symbols.defn.isFunctionType(fn.tpe) =>
val app1 = dotc.transform.BetaReduce(app, fn, List(args))
if app1 eq app then None
else Some(app1.withSpan(tree.span))
case app @ tpd.Apply(tpd.TypeApply(tpd.Select(fn, nme.apply), targs), args) if fn.tpe.typeSymbol eq dotc.core.Symbols.defn.PolyFunctionClass =>
val app1 = dotc.transform.BetaReduce(app, fn, List(targs, app.args))
if app1 eq app then None
else Some(app1.withSpan(tree.span))
case tpd.Block(Nil, expr) =>
for e <- betaReduce(expr) yield tpd.cpy.Block(tree)(Nil, e)
case tpd.Inlined(_, Nil, expr) =>
Expand Down
15 changes: 15 additions & 0 deletions tests/run-macros/i15968/Macro_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
import scala.quoted.*

inline def macroPolyFun[A](inline arg: A, inline f: [Z] => Z => String): String =
${ macroPolyFunImpl[A]('arg, 'f) }

private def macroPolyFunImpl[A: Type](arg: Expr[A], f: Expr[[Z] => Z => String])(using Quotes): Expr[String] =
Expr(Expr.betaReduce('{ $f($arg) }).show)


inline def macroFun[A](inline arg: A, inline f: A => String): String =
${ macroFunImpl[A]('arg, 'f) }

private def macroFunImpl[A: Type](arg: Expr[A], f: Expr[A => String])(using Quotes): Expr[String] =
Expr(Expr.betaReduce('{ $f($arg) }).show)

3 changes: 3 additions & 0 deletions tests/run-macros/i15968/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
@main def Test: Unit =
println(macroPolyFun("foo", [Z] => (arg: Z) => arg.toString))
println(macroFun("foo", arg => arg.toString))

0 comments on commit 7e4fe17

Please sign in to comment.