From d101327b9937f319f704d607cd9578b133b82454 Mon Sep 17 00:00:00 2001 From: Nicolas Stucki Date: Tue, 27 Apr 2021 11:04:20 +0200 Subject: [PATCH] Support inline val references in top level splices Fixes #12196 --- compiler/src/dotty/tools/dotc/transform/Splicer.scala | 8 +++++++- tests/neg-macros/i7839.check | 1 + tests/neg/i12196.scala | 10 ++++++++++ tests/neg/i12196b.scala | 10 ++++++++++ tests/pos-macros/i12196/Macros_1.scala | 8 ++++++++ tests/pos-macros/i12196/Test_2.scala | 1 + 6 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 tests/neg/i12196.scala create mode 100644 tests/neg/i12196b.scala create mode 100644 tests/pos-macros/i12196/Macros_1.scala create mode 100644 tests/pos-macros/i12196/Test_2.scala diff --git a/compiler/src/dotty/tools/dotc/transform/Splicer.scala b/compiler/src/dotty/tools/dotc/transform/Splicer.scala index 6fb008c88889..b150414d11ee 100644 --- a/compiler/src/dotty/tools/dotc/transform/Splicer.scala +++ b/compiler/src/dotty/tools/dotc/transform/Splicer.scala @@ -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 _ => @@ -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) } @@ -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] + 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)) diff --git a/tests/neg-macros/i7839.check b/tests/neg-macros/i7839.check index 197867ab809b..3e3fc7b2c0f1 100644 --- a/tests/neg-macros/i7839.check +++ b/tests/neg-macros/i7839.check @@ -6,3 +6,4 @@ | Parameters may only be: | * Quoted parameters or fields | * Literal values of primitive types + | * References to `inline val`s diff --git a/tests/neg/i12196.scala b/tests/neg/i12196.scala new file mode 100644 index 000000000000..91619ad3c387 --- /dev/null +++ b/tests/neg/i12196.scala @@ -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") } diff --git a/tests/neg/i12196b.scala b/tests/neg/i12196b.scala new file mode 100644 index 000000000000..3bd606d9b62e --- /dev/null +++ b/tests/neg/i12196b.scala @@ -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 diff --git a/tests/pos-macros/i12196/Macros_1.scala b/tests/pos-macros/i12196/Macros_1.scala new file mode 100644 index 000000000000..60e1f56b0b3d --- /dev/null +++ b/tests/pos-macros/i12196/Macros_1.scala @@ -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) diff --git a/tests/pos-macros/i12196/Test_2.scala b/tests/pos-macros/i12196/Test_2.scala new file mode 100644 index 000000000000..a4b3e340cb52 --- /dev/null +++ b/tests/pos-macros/i12196/Test_2.scala @@ -0,0 +1 @@ +def test = withInlineVal