Skip to content

Support inline val references in top level splices #12235

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

Merged
merged 1 commit into from
Apr 28, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 7 additions & 1 deletion compiler/src/dotty/tools/dotc/transform/Splicer.scala
Original file line number Diff line number Diff line change
Expand Up @@ -161,7 +161,7 @@ object Splicer {
case SeqLiteral(elems, _) =>
elems.foreach(checkIfValidArgument)

case tree: Ident if summon[Env].contains(tree.symbol) =>
case tree: Ident if summon[Env].contains(tree.symbol) || tree.symbol.is(Inline, butNot = Method) =>
// OK

case _ =>
Expand All @@ -172,6 +172,7 @@ object Splicer {
|Parameters may only be:
| * Quoted parameters or fields
| * Literal values of primitive types
| * References to `inline val`s
|""".stripMargin, tree.srcPos)
}

Expand Down Expand Up @@ -242,6 +243,11 @@ object Splicer {
case Literal(Constant(value)) =>
interpretLiteral(value)

case tree: Ident if tree.symbol.is(Inline, butNot = Method) =>
tree.tpe.widenTermRefExpr match
case ConstantType(c) => c.value.asInstanceOf[Object]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should probably handle null here too

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do not support inline val n = null. That should be added when we add support for it and can write a test case for that logic.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See #12198

case _ => throw new StopInterpretation(em"${tree.symbol} could not be inlined", tree.srcPos)

// TODO disallow interpreted method calls as arguments
case Call(fn, args) =>
if (fn.symbol.isConstructor && fn.symbol.owner.owner.is(Package))
Expand Down
1 change: 1 addition & 0 deletions tests/neg-macros/i7839.check
Original file line number Diff line number Diff line change
Expand Up @@ -6,3 +6,4 @@
| Parameters may only be:
| * Quoted parameters or fields
| * Literal values of primitive types
| * References to `inline val`s
10 changes: 10 additions & 0 deletions tests/neg/i12196.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import scala.quoted.*

def qqq(s: String)(using Quotes): Expr[Unit] = '{()}

inline val InlineVal = "i"
inline def InlineDef = "i"

inline def withInlineVal = ${ qqq(InlineVal) }
inline def withInlineDef = ${ qqq(InlineDef) } // error
inline def withString = ${ qqq("i") }
10 changes: 10 additions & 0 deletions tests/neg/i12196b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
import scala.quoted.*

def qqq(s: String)(using Quotes): Expr[Unit] = '{()}

abstract class Foo:
inline val InlineVal: String

val foo: Foo = ???

inline def withInlineVal = ${ qqq(foo.InlineVal) } // error
8 changes: 8 additions & 0 deletions tests/pos-macros/i12196/Macros_1.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@

import scala.quoted.*

inline val InlineStringVal = "abc"

inline def withInlineVal = ${ qqq(InlineStringVal) }

def qqq(s: String)(using Quotes): Expr[String] = Expr(s)
1 change: 1 addition & 0 deletions tests/pos-macros/i12196/Test_2.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
def test = withInlineVal