-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Closed
Labels
area:metaprogramming:reflectionIssues related to the quotes reflection APIIssues related to the quotes reflection APIitype:bug
Milestone
Description
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
Labels
area:metaprogramming:reflectionIssues related to the quotes reflection APIIssues related to the quotes reflection APIitype:bug
Type
Projects
Relationships
Development
Select code repository
Activity
jchyb commentedon Jun 28, 2023
I did some quick experiments and I discovered two things:
Term.betaReduce
andExpr.betaReduce
are unable to beta reduce the curried function. The difference lies only in how this behavior is handled in their APIs.My test (mostly just printlns with inline parameters added for readability to the previous minimization):
Macro.scala
MacroTest.scala
Output
nicolasstucki commentedon Jun 28, 2023
Interesting. The behavior is consistent and correct, but we do have room for improvement.
The core bera reduction logic seems to be able to reduce such expressions. For example the following code is reduced after the bata reduction phase.
nicolasstucki commentedon Jun 28, 2023
@jchyb there might be a bug in https://github.com/lampepfl/dotty/blob/main/compiler/src/scala/quoted/runtime/impl/QuotesImpl.scala#L373-L382 or maybe the issue is in https://github.com/lampepfl/dotty/blob/main/compiler/src/dotty/tools/dotc/transform/BetaReduce.scala#L74