Skip to content

Commit 257d7b4

Browse files
committed
Fix #4456: Pickle quote before compiling
1 parent 48a2f4b commit 257d7b4

File tree

8 files changed

+41
-8
lines changed

8 files changed

+41
-8
lines changed

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,13 @@ import scala.reflect.ClassTag
2222
object PickledQuotes {
2323
import tpd._
2424

25-
/** Pickle the quote into strings */
25+
/** Pickle the tree of the a quoted.Expr */
26+
def pickleExpr(tree: Tree)(implicit ctx: Context): scala.quoted.Expr[Any] = {
27+
val pickled = pickleQuote(tree)
28+
scala.runtime.quoted.Unpickler.unpickleExpr(pickled, Nil)
29+
}
30+
31+
/** Pickle the tree of the quote into strings */
2632
def pickleQuote(tree: Tree)(implicit ctx: Context): scala.runtime.quoted.Unpickler.Pickled = {
2733
if (ctx.reporter.hasErrors) Nil
2834
else {

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ import scala.collection.{ mutable, immutable }
1919
import config.Printers.pickling
2020
import typer.Checking
2121
import config.Config
22-
import dotty.tools.dotc.core.quoted.PickledQuotes
22+
import core.quoted.PickledQuotes
2323
import scala.quoted
2424
import scala.quoted.Types.TreeType
2525
import scala.quoted.Exprs.TreeExpr
@@ -1142,7 +1142,7 @@ class TreeUnpickler(reader: TastyReader,
11421142
val idx = readNat()
11431143
val args = until(end)(readTerm())
11441144
val splice = splices(idx)
1145-
val reifiedArgs = args.map(arg => if (arg.isTerm) new TreeExpr(arg) else new TreeType(arg))
1145+
val reifiedArgs = args.map(arg => if (arg.isTerm) new TreeExpr(arg, PickledQuotes.pickleExpr(arg)) else new TreeType(arg))
11461146
if (isType) {
11471147
val quotedType = splice.asInstanceOf[Seq[Any] => quoted.Type[_]](reifiedArgs)
11481148
PickledQuotes.quotedTypeToTree(quotedType)

compiler/src/dotty/tools/dotc/quoted/Toolbox.scala

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,13 @@ package dotty.tools.dotc.quoted
33
import dotty.tools.dotc.ast.Trees._
44
import dotty.tools.dotc.ast.tpd
55
import dotty.tools.dotc.core.Constants._
6+
import dotty.tools.dotc.core.Contexts.Context
7+
import dotty.tools.dotc.core.quoted.PickledQuotes
68
import dotty.tools.dotc.printing.RefinedPrinter
79

810
import scala.quoted.Expr
911
import scala.runtime.BoxedUnit
10-
import scala.quoted.Exprs.LiftedExpr
12+
import scala.quoted.Exprs.{LiftedExpr, TreeExpr}
1113
import scala.runtime.quoted._
1214

1315
/** Default runners for quoted expressions */
@@ -23,8 +25,12 @@ object Toolbox {
2325
): Toolbox[T] = new Toolbox[T] {
2426

2527
def run(expr: Expr[T]): T = expr match {
26-
case expr: LiftedExpr[T] => expr.value
27-
case _ => new QuoteDriver().run(expr, runSettings)
28+
case expr: LiftedExpr[T] =>
29+
expr.value
30+
case expr: TreeExpr[Tree] @unchecked =>
31+
new QuoteDriver().run(expr.pickled, runSettings)
32+
case _ =>
33+
new QuoteDriver().run(expr, runSettings)
2834
}
2935

3036
def show(expr: Expr[T]): String = expr match {

compiler/src/dotty/tools/dotc/transform/Splicer.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,8 @@ object Splicer {
6060
case (arg, tp) =>
6161
assert(!tp.hasAnnotation(defn.InlineParamAnnot))
6262
// Replace argument by its binding
63-
new scala.quoted.Exprs.TreeExpr(bindMap.getOrElse(arg, arg))
63+
val arg1 = bindMap.getOrElse(arg, arg)
64+
new scala.quoted.Exprs.TreeExpr(arg1, PickledQuotes.pickleExpr(arg1))
6465
}
6566
args1 ::: liftArgs(tp.resType, args.tail)
6667
case tp: PolyType =>

library/src/scala/quoted/Expr.scala

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ object Exprs {
3737
}
3838

3939
/** An Expr backed by a tree. Only the current compiler trees are allowed. */
40-
final class TreeExpr[Tree](val tree: Tree) extends quoted.Expr[Any] {
40+
final class TreeExpr[Tree](val tree: Tree, pickle: => Expr[_]) extends quoted.Expr[Any] {
41+
def pickled[T]: Expr[T] = pickle.asInstanceOf[Expr[T]]
4142
override def toString: String = s"Expr(<raw>)"
4243
}
4344

tests/run/quote-run-in-macro-1.check

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
1
2+
4
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
import scala.quoted._
2+
3+
import dotty.tools.dotc.quoted.Toolbox._
4+
5+
object Macros {
6+
inline def foo(i: Int): Int = ~{
7+
val y: Int = ('(i)).run
8+
y.toExpr
9+
}
10+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
import Macros._
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
println(foo(1))
5+
println(foo(1 + 3))
6+
}
7+
}

0 commit comments

Comments
 (0)