Skip to content

Commit c963249

Browse files
Merge pull request #4576 from dotty-staging/disable-macro-quote-run
Do not allow running Expr that came as macro arguments
2 parents 902f4cb + 4d4d592 commit c963249

File tree

12 files changed

+14
-69
lines changed

12 files changed

+14
-69
lines changed

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

Lines changed: 1 addition & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,6 @@ object PickledQuotes {
2323

2424
/** Pickle the tree of the quoted.Expr */
2525
def pickleExpr(tree: Tree)(implicit ctx: Context): scala.quoted.Expr[Any] = {
26-
// Check that there are no free variables
27-
new TreeTraverser {
28-
private val definedHere = scala.collection.mutable.Set.empty[Symbol]
29-
def traverse(tree: tpd.Tree)(implicit ctx: Context): Unit = tree match {
30-
case tree: Ident if tree.symbol.exists && !definedHere(tree.symbol) =>
31-
throw new scala.quoted.FreeVariableError(tree.name.toString)
32-
case tree: DefTree =>
33-
definedHere += tree.symbol
34-
traverseChildren(tree)
35-
case _ =>
36-
traverseChildren(tree)
37-
}
38-
}.traverse(tree)
3926
val pickled = pickleQuote(tree)
4027
scala.runtime.quoted.Unpickler.unpickleExpr(pickled, Nil)
4128
}
@@ -64,7 +51,7 @@ object PickledQuotes {
6451
case value: Class[_] => ref(defn.Predef_classOf).appliedToType(classToType(value))
6552
case value => Literal(Constant(value))
6653
}
67-
case expr: TreeExpr[Tree] @unchecked => expr.tree
54+
case expr: TastyTreeExpr[Tree] @unchecked => expr.tree
6855
case expr: FunctionAppliedTo[_, _] =>
6956
functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x))
7057
}

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ import config.Config
2222
import core.quoted.PickledQuotes
2323
import scala.quoted
2424
import scala.quoted.Types.TreeType
25-
import scala.quoted.Exprs.TreeExpr
25+
import scala.quoted.Exprs.TastyTreeExpr
2626

2727
/** Unpickler for typed trees
2828
* @param reader the reader from which to unpickle
@@ -1150,7 +1150,7 @@ class TreeUnpickler(reader: TastyReader,
11501150
val args = until(end)(readTerm())
11511151
val splice = splices(idx)
11521152
def wrap(arg: Tree) =
1153-
if (arg.isTerm) new TreeExpr(arg, PickledQuotes.pickleExpr(arg))
1153+
if (arg.isTerm) new TastyTreeExpr(arg)
11541154
else new TreeType(arg)
11551155
val reifiedArgs = args.map(wrap)
11561156
if (isType) {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import dotty.tools.dotc.printing.RefinedPrinter
66

77
import scala.quoted.Expr
88
import scala.runtime.BoxedUnit
9-
import scala.quoted.Exprs.{LiftedExpr, TreeExpr}
9+
import scala.quoted.Exprs.{LiftedExpr, TastyTreeExpr}
1010
import scala.runtime.quoted._
1111

1212
/** Default runners for quoted expressions */
@@ -24,8 +24,8 @@ object Toolbox {
2424
def run(expr: Expr[T]): T = expr match {
2525
case expr: LiftedExpr[T] =>
2626
expr.value
27-
case expr: TreeExpr[Tree] @unchecked =>
28-
new QuoteDriver().run(expr.pickled, runSettings)
27+
case expr: TastyTreeExpr[Tree] @unchecked =>
28+
throw new Exception("Cannot call `Expr.run` on an `Expr` that comes from an inline macro argument.")
2929
case _ =>
3030
new QuoteDriver().run(expr, runSettings)
3131
}

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ object Splicer {
6868
assert(!tp.hasAnnotation(defn.InlineParamAnnot))
6969
// Replace argument by its binding
7070
val arg1 = bindMap.getOrElse(arg, arg)
71-
new scala.quoted.Exprs.TreeExpr(arg1, PickledQuotes.pickleExpr(arg1))
71+
new scala.quoted.Exprs.TastyTreeExpr(arg1)
7272
}
7373
args1 ::: liftArgs(tp.resType, args.tail)
7474
case tp: PolyType =>

library/src/scala/quoted/Expr.scala

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ object Expr {
3333
object Exprs {
3434
/** An Expr backed by a pickled TASTY tree */
3535
final class TastyExpr[T](val tasty: Pickled, val args: Seq[Any]) extends Expr[T] {
36-
override def toString: String = s"Expr(<pickled>)"
36+
override def toString: String = s"Expr(<pickled tasty>)"
3737
}
3838

3939
/** An Expr backed by a lifted value.
@@ -48,11 +48,10 @@ object Exprs {
4848
* These expressions are used for arguments of inline macros. They contain and actual tree
4949
* from the program that is being expanded by the macro.
5050
*
51-
* May contain references to code defined outside this Expr instance.
51+
* May contain references to code defined outside this TastyTreeExpr instance.
5252
*/
53-
final class TreeExpr[Tree](val tree: Tree, pickle: => Expr[_]) extends quoted.Expr[Any] {
54-
def pickled[T]: Expr[T] = pickle.asInstanceOf[Expr[T]]
55-
override def toString: String = s"Expr(<raw>)"
53+
final class TastyTreeExpr[Tree](val tree: Tree) extends quoted.Expr[Any] {
54+
override def toString: String = s"Expr(<tasty tree>)"
5655
}
5756

5857
/** An Expr representing `'{(~f).apply(~x)}` but it is beta-reduced when the closure is known */

library/src/scala/quoted/FreeVariableError.scala

Lines changed: 0 additions & 8 deletions
This file was deleted.

tests/run/quote-run-in-macro-1/quoted_2.scala renamed to tests/neg/quote-run-in-macro-2/quoted_2.scala

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import Macros._
22
object Test {
33
def main(args: Array[String]): Unit = {
4-
println(foo(1))
5-
println(foo(1 + 3))
4+
println(foo(1)) // error
5+
println(foo(1 + 3)) // error
66
val x = 3
7-
println(foo {
7+
println(foo { // error
88
val x = 5
99
x
1010
})

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

Lines changed: 0 additions & 3 deletions
This file was deleted.

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

Lines changed: 0 additions & 3 deletions
This file was deleted.

tests/run/quote-run-in-macro-2/quoted_1.scala

Lines changed: 0 additions & 18 deletions
This file was deleted.

tests/run/quote-run-in-macro-2/quoted_2.scala

Lines changed: 0 additions & 9 deletions
This file was deleted.

0 commit comments

Comments
 (0)