Skip to content

Expr.value not resolving for inline argument defaults #11835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
japgolly opened this issue Mar 21, 2021 · 2 comments · Fixed by #11840
Closed

Expr.value not resolving for inline argument defaults #11835

japgolly opened this issue Mar 21, 2021 · 2 comments · Fixed by #11840
Assignees
Milestone

Comments

@japgolly
Copy link
Contributor

Compiler version

3.0.0-RC1

Minimized code

X.scala

import scala.quoted.*

object X:
  inline def blah(inline b: Boolean = true): Unit =
    ${ _blah('b) }

  private def _blah(b: Expr[Boolean])(using Quotes): Expr[Unit] =
    import quotes.reflect.*
    println("="*120)
    println(b.asTerm)
    println(b.valueOrError)
    '{()}

Y.scala

object Y:
  X.blah(true) // ok
  X.blah()     // error

Output

========================================================================================================================
Inlined(EmptyTree,List(),Literal(Constant(true)))
true
========================================================================================================================
Inlined(EmptyTree,List(),Select(Ident(X),blah$default$1))
[error] -- Error: Y.scala:3:4 
[error] 3 |  X.blah()
[error]   |  ^^^^^^
[error]   |Expected a known value. 
[error]   |
[error]   |The value of: X.blah$default$1
[error]   |could not be extracted using scala.quoted.FromExpr$PrimitiveFromExpr@1b05809c
[error]   | This location contains code that was inlined from Y.scala:3

Expectation

Expr.valueOrError should work for inline default arguments (or at least those with constants as values). It seems that the compiler is generating a blah$default$1 rather than just keeping the Literal(Constant(true)).

The use case here is being able to have macros with configuration flags. The flags have defaults that users can optionally override (i.e. specify) when calling the inline macro method.

It would be easier than trying unwrap Exprs, if we could pass inline arguments directly from the public inline method to the non-inline quoted one like this:

  inline def blah(inline b: Boolean = true): Unit =
    ${ _blah(b) }

  private def _blah(b: Boolean)(using Quotes): Expr[Unit] =
    '{()}
@liufengyun
Copy link
Contributor

The following seems to be a workaround:

  inline def blah(inline b: Boolean): Unit =
    ${ _blah('b) }

  inline def blah(): Unit =
    ${ _blah('{true}) }

To address the problem more directly, maybe we should keep the inline flag for default values.

@liufengyun liufengyun self-assigned this Mar 22, 2021
liufengyun added a commit to dotty-staging/dotty that referenced this issue Mar 22, 2021
nicolasstucki added a commit that referenced this issue Mar 23, 2021
Fix #11835: respect inline flag for default values of inline parameters
@japgolly
Copy link
Contributor Author

Nice, thank you @liufengyun !

@Kordyjan Kordyjan added this to the 3.0.0 milestone Aug 2, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants