Skip to content

Commit e62b52c

Browse files
Merge pull request #4384 from dotty-staging/fix-#4380
Fix #4380: Revert optimization that breaks owners
2 parents d73d9bc + dec41d1 commit e62b52c

File tree

4 files changed

+48
-31
lines changed

4 files changed

+48
-31
lines changed

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

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1142,14 +1142,10 @@ class TreeUnpickler(reader: TastyReader,
11421142
val splice = splices(idx)
11431143
val reifiedArgs = args.map(arg => if (arg.isTerm) new TreeExpr(arg) else new TreeType(arg))
11441144
if (isType) {
1145-
val quotedType =
1146-
if (reifiedArgs.isEmpty) splice.asInstanceOf[quoted.Type[_]]
1147-
else splice.asInstanceOf[Seq[Any] => quoted.Type[_]](reifiedArgs)
1145+
val quotedType = splice.asInstanceOf[Seq[Any] => quoted.Type[_]](reifiedArgs)
11481146
PickledQuotes.quotedTypeToTree(quotedType)
11491147
} else {
1150-
val quotedExpr =
1151-
if (reifiedArgs.isEmpty) splice.asInstanceOf[quoted.Expr[_]]
1152-
else splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](reifiedArgs)
1148+
val quotedExpr = splice.asInstanceOf[Seq[Any] => quoted.Expr[_]](reifiedArgs)
11531149
PickledQuotes.quotedExprToTree(quotedExpr)
11541150
}
11551151
}

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

Lines changed: 15 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,6 @@ import dotty.tools.dotc.core.quoted._
3232
* val x2 = ???
3333
* ...
3434
* ~{ ... '{ ... x1 ... x2 ...} ... }
35-
* ~{ ... /* no references to xi */ ... }
3635
* ...
3736
* }
3837
* ```
@@ -45,7 +44,6 @@ import dotty.tools.dotc.core.quoted._
4544
* val x2 = ???
4645
* ...
4746
* Hole(0 | x1, x2)
48-
* Hole(1 | )
4947
* ...
5048
* ]],
5149
* List(
@@ -54,8 +52,7 @@ import dotty.tools.dotc.core.quoted._
5452
* val x2$1 = args(1).asInstanceOf[Expr[T]] // can be asInstanceOf[Type[T]]
5553
* ...
5654
* { ... '{ ... x1$1.unary_~ ... x2$1.unary_~ ...} ... }
57-
* },
58-
* { ... /* no references to xi */ ... } // optimized to not create lambda
55+
* }
5956
* )
6057
* )
6158
* ```
@@ -69,12 +66,12 @@ import dotty.tools.dotc.core.quoted._
6966
* ```
7067
* to
7168
* ```
72-
* inline def foo[T1, ...](inline x1: X, ..., y1: Y, ....): Object = { (args: Seq[Any]) => {
69+
* inline def foo[T1, ...](inline x1: X, ..., y1: Y, ....): Seq[Any] => Object = { (args: Seq[Any]) => {
7370
* val T1$1 = args(0).asInstanceOf[Type[T1]]
7471
* ...
75-
* val x1$1 = args(..).asInstanceOf[X]
72+
* val x1$1 = args(0).asInstanceOf[X]
7673
* ...
77-
* val y1$1 = args(..).asInstanceOf[Expr[Y]]
74+
* val y1$1 = args(1).asInstanceOf[Expr[Y]]
7875
* ...
7976
* { ... T1$1.unary_~ ... x ... '(y1$1.unary_~) ... }
8077
* }
@@ -448,8 +445,6 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
448445
* val y$1 = args(1).asInstanceOf[Expr[Any]] // or .asInstanceOf[Type[Any]]
449446
* { ... '{ ... x$1.unary_~ ... y$1.unary_~ ... } ... }
450447
* }
451-
* or if the spliced subexpression has no captures it will be transformed to
452-
* { ... '{ ... x$1.unary_~ ... y$1.unary_~ ... } ... }
453448
*
454449
* See: `capture`
455450
*
@@ -462,19 +457,6 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
462457
* }
463458
*/
464459
private def makeLambda(tree: Tree)(implicit ctx: Context): Tree = {
465-
var treeWithoutCaptures: Tree = null
466-
def transformWithCapturer(tree: Tree)(capturer: mutable.Map[Symbol, Tree] => Tree => Tree)(implicit ctx: Context): Tree = {
467-
val captured = mutable.LinkedHashMap.empty[Symbol, Tree]
468-
val captured2 = capturer(captured)
469-
outer.enteredSyms.foreach(s => capturers.put(s, captured2))
470-
if (ctx.owner.owner.is(Macro))
471-
outer.enteredSyms.reverse.foreach(s => captured2(ref(s)))
472-
val tree2 = transform(tree)
473-
capturers --= outer.enteredSyms
474-
if (captured.isEmpty)
475-
treeWithoutCaptures = tree2
476-
seq(captured.result().valuesIterator.toList, tree2)
477-
}
478460
def body(arg: Tree)(implicit ctx: Context): Tree = {
479461
var i = 0
480462
transformWithCapturer(tree)(
@@ -502,10 +484,18 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
502484
val lambdaOwner = ctx.owner.ownersIterator.find(o => levelOf.getOrElse(o, level) == level).get
503485
val tpe = MethodType(defn.SeqType.appliedTo(defn.AnyType) :: Nil, tree.tpe.widen)
504486
val meth = ctx.newSymbol(lambdaOwner, UniqueName.fresh(nme.ANON_FUN), Synthetic | Method, tpe)
505-
val closure = Closure(meth, tss => body(tss.head.head)(ctx.withOwner(meth)).changeOwner(ctx.owner, meth))
487+
Closure(meth, tss => body(tss.head.head)(ctx.withOwner(meth)).changeOwner(ctx.owner, meth))
488+
}
506489

507-
if (treeWithoutCaptures == null || ctx.owner.is(Macro)) closure
508-
else treeWithoutCaptures
490+
private def transformWithCapturer(tree: Tree)(capturer: mutable.Map[Symbol, Tree] => Tree => Tree)(implicit ctx: Context): Tree = {
491+
val captured = mutable.LinkedHashMap.empty[Symbol, Tree]
492+
val captured2 = capturer(captured)
493+
outer.enteredSyms.foreach(s => capturers.put(s, captured2))
494+
if (ctx.owner.owner.is(Macro))
495+
outer.enteredSyms.reverse.foreach(s => captured2(ref(s)))
496+
val tree2 = transform(tree)
497+
capturers --= outer.enteredSyms
498+
seq(captured.result().valuesIterator.toList, tree2)
509499
}
510500

511501
/** Returns true if this tree will be captured by `makeLambda` */

tests/pos/i4380a.scala

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import scala.quoted._
2+
3+
object Test {
4+
5+
trait Producer[A] { self =>
6+
def step(k: (A => Expr[Unit])): Expr[Unit]
7+
}
8+
9+
trait Foo[A]
10+
case class Bar[A, B](producer: Producer[B], nestedf: B => Expr[Unit]) extends Foo[A]
11+
12+
def meth[A](stream: Foo[Expr[A]]): Producer[Expr[A]] = {
13+
stream match {
14+
case Bar(producer, nestedf) => {
15+
new Producer[Expr[A]] {
16+
def step(k: Expr[A] => Expr[Unit]): Expr[Unit] = '{
17+
val adv: Unit => Unit = { _ => ~producer.step((el) => nestedf(el))}
18+
}
19+
}
20+
}
21+
}
22+
}
23+
}

tests/pos/i4380b.scala

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.quoted._
2+
3+
object Test {
4+
def step(k: (String => Expr[Unit])): Expr[Unit] = '()
5+
def meth(): Unit = '{
6+
(i: Int) => ~step(el => '() )
7+
}
8+
}

0 commit comments

Comments
 (0)