Skip to content

Commit 9550ba8

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

File tree

8 files changed

+31
-6
lines changed

8 files changed

+31
-6
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@ object PickledQuotes {
4141
case value: Class[_] => ref(defn.Predef_classOf).appliedToType(classToType(value))
4242
case value=> Literal(Constant(value))
4343
}
44-
case expr: TreeExpr[Tree] @unchecked => expr.tree
44+
case expr: TreeExpr[Tree, Context] @unchecked => expr.tree
4545
case expr: FunctionAppliedTo[_, _] =>
4646
functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x))
4747
}

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, ctx) 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: 7 additions & 1 deletion
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 */
@@ -24,6 +26,10 @@ object Toolbox {
2426

2527
def run(expr: Expr[T]): T = expr match {
2628
case expr: LiftedExpr[T] => expr.value
29+
case expr: TreeExpr[Tree, Context] @unchecked =>
30+
val pickled = PickledQuotes.pickleQuote(expr.tree)(expr.ctx)
31+
val pickledQuote = scala.runtime.quoted.Unpickler.unpickleExpr(pickled, Nil)
32+
new QuoteDriver().run(pickledQuote, runSettings)
2733
case _ => new QuoteDriver().run(expr, runSettings)
2834
}
2935

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,7 @@ 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+
new scala.quoted.Exprs.TreeExpr(bindMap.getOrElse(arg, arg), ctx)
6464
}
6565
args1 ::: liftArgs(tp.resType, args.tail)
6666
case tp: PolyType =>

library/src/scala/quoted/Expr.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ 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, Ctx](val tree: Tree, val ctx: Ctx) extends quoted.Expr[Any] {
4141
override def toString: String = s"Expr(<raw>)"
4242
}
4343

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)