Skip to content

Term.betaReduce not working for curried context functions #17506

Closed
@prolativ

Description

@prolativ

Compiler version

3.3.1-RC1-bin-20230514-b0ccf40-NIGHTLY and before

Minimized code

Macro.scala

import scala.quoted.*

class Foo
class Bar

inline def fooCurriedExpr(f: Foo ?=> Bar ?=> Int): Int = ${ fooCurriedExprImpl('f) }

def fooCurriedExprImpl(f: Expr[Foo ?=> Bar ?=> Int])(using Quotes) =
  val applied = '{ ${f}(using new Foo)(using new Bar) }
  Expr.betaReduce(applied)

inline def fooCurriedReflect(f: Foo ?=> Bar ?=> Int): Int = ${ fooCurriedReflectImpl('f) }

def fooCurriedReflectImpl(f: Expr[Foo ?=> Bar ?=> Int])(using Quotes) =
  val applied = '{ ${f}(using new Foo)(using new Bar) }
  import quotes.reflect.*
  Term.betaReduce(applied.asTerm).get.asExprOf[Int]

inline def fooTupledExpr(f: (Foo, Bar) ?=> Int): Int = ${ fooTupledExprImpl('f) }

def fooTupledExprImpl(f: Expr[(Foo, Bar) ?=> Int])(using Quotes) =
  val applied = '{ ${f}(using new Foo, new Bar) }
  Expr.betaReduce(applied)

inline def fooTupledReflect(f: (Foo, Bar) ?=> Int): Int = ${ fooTupledReflectImpl('f) }

def fooTupledReflectImpl(f: Expr[(Foo, Bar) ?=> Int])(using Quotes) =
  val applied = '{ ${f}(using new Foo, new Bar) }
  import quotes.reflect.*
  Term.betaReduce(applied.asTerm).get.asExprOf[Int]

MacroTest.scala:

@main def run() =
  println(fooCurriedExpr(123))
  println(fooCurriedReflect(123))
  println(fooTupledExpr(123))
  println(fooTupledReflect(123))

Output

[error] MacroTest.scala:3:11
[error] Exception occurred while executing macro expansion.
[error] java.util.NoSuchElementException: None.get
[error]         at scala.None$.get(Option.scala:627)
[error]         at scala.None$.get(Option.scala:626)
[error]         at Macro$package$.fooCurriedReflectImpl(Macro.scala:17)
[error] 
[error]   println(fooCurriedReflect(123))
[error]           ^^^^^^^^^^^^^^^^^^^^^^

After commenting out println(fooCurriedReflect(123)) the code compiles successfully.

Expectation

The code should compile as is. Term.betaReduce should successfully reduce an application of a curried context function (returning Some rather than None) just a it does for a tupled context function.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions