@@ -32,6 +32,7 @@ import dotty.tools.dotc.core.quoted._
32
32
* val x2 = ???
33
33
* ...
34
34
* ~{ ... '{ ... x1 ... x2 ...} ... }
35
+ * ~{ ... /* no references to xi */ ... }
35
36
* ...
36
37
* }
37
38
* ```
@@ -44,6 +45,7 @@ import dotty.tools.dotc.core.quoted._
44
45
* val x2 = ???
45
46
* ...
46
47
* Hole(0 | x1, x2)
48
+ * Hole(1 | )
47
49
* ...
48
50
* ]],
49
51
* List(
@@ -52,7 +54,8 @@ import dotty.tools.dotc.core.quoted._
52
54
* val x2$1 = args(1).asInstanceOf[Expr[T]] // can be asInstanceOf[Type[T]]
53
55
* ...
54
56
* { ... '{ ... x1$1.unary_~ ... x2$1.unary_~ ...} ... }
55
- * }
57
+ * },
58
+ * { ... /* no references to xi */ ... } // optimized to not create lambda
56
59
* )
57
60
* )
58
61
* ```
@@ -66,12 +69,12 @@ import dotty.tools.dotc.core.quoted._
66
69
* ```
67
70
* to
68
71
* ```
69
- * inline def foo[T1, ...](inline x1: X, ..., y1: Y, ....): Seq[Any] => Object = { (args: Seq[Any]) => {
72
+ * inline def foo[T1, ...](inline x1: X, ..., y1: Y, ....): Object = { (args: Seq[Any]) => {
70
73
* val T1$1 = args(0).asInstanceOf[Type[T1]]
71
74
* ...
72
- * val x1$1 = args(0 ).asInstanceOf[X]
75
+ * val x1$1 = args(.. ).asInstanceOf[X]
73
76
* ...
74
- * val y1$1 = args(1 ).asInstanceOf[Expr[Y]]
77
+ * val y1$1 = args(.. ).asInstanceOf[Expr[Y]]
75
78
* ...
76
79
* { ... T1$1.unary_~ ... x ... '(y1$1.unary_~) ... }
77
80
* }
@@ -417,6 +420,8 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
417
420
* val y$1 = args(1).asInstanceOf[Expr[Any]] // or .asInstanceOf[Type[Any]]
418
421
* { ... '{ ... x$1.unary_~ ... y$1.unary_~ ... } ... }
419
422
* }
423
+ * or if the spliced subexpression has no captures it will be transformed to
424
+ * { ... '{ ... x$1.unary_~ ... y$1.unary_~ ... } ... }
420
425
*
421
426
* See: `capture`
422
427
*
@@ -429,6 +434,19 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
429
434
* }
430
435
*/
431
436
private def makeLambda (tree : Tree )(implicit ctx : Context ): Tree = {
437
+ var treeWithoutCaptures : Tree = null
438
+ def transformWithCapturer (tree : Tree )(capturer : mutable.Map [Symbol , Tree ] => Tree => Tree )(implicit ctx : Context ): Tree = {
439
+ val captured = mutable.LinkedHashMap .empty[Symbol , Tree ]
440
+ val captured2 = capturer(captured)
441
+ outer.enteredSyms.foreach(s => capturers.put(s, captured2))
442
+ if (ctx.owner.owner.is(Macro ))
443
+ outer.enteredSyms.reverse.foreach(s => captured2(ref(s)))
444
+ val tree2 = transform(tree)
445
+ capturers --= outer.enteredSyms
446
+ if (captured.isEmpty)
447
+ treeWithoutCaptures = tree2
448
+ seq(captured.result().valuesIterator.toList, tree2)
449
+ }
432
450
def body (arg : Tree )(implicit ctx : Context ): Tree = {
433
451
var i = 0
434
452
transformWithCapturer(tree)(
@@ -456,18 +474,10 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
456
474
val lambdaOwner = ctx.owner.ownersIterator.find(o => levelOf.getOrElse(o, level) == level).get
457
475
val tpe = MethodType (defn.SeqType .appliedTo(defn.AnyType ) :: Nil , tree.tpe.widen)
458
476
val meth = ctx.newSymbol(lambdaOwner, UniqueName .fresh(nme.ANON_FUN ), Synthetic | Method , tpe)
459
- Closure (meth, tss => body(tss.head.head)(ctx.withOwner(meth)).changeOwner(ctx.owner, meth))
460
- }
477
+ val closure = Closure (meth, tss => body(tss.head.head)(ctx.withOwner(meth)).changeOwner(ctx.owner, meth))
461
478
462
- private def transformWithCapturer (tree : Tree )(capturer : mutable.Map [Symbol , Tree ] => Tree => Tree )(implicit ctx : Context ): Tree = {
463
- val captured = mutable.LinkedHashMap .empty[Symbol , Tree ]
464
- val captured2 = capturer(captured)
465
- outer.enteredSyms.foreach(s => capturers.put(s, captured2))
466
- if (ctx.owner.owner.is(Macro ))
467
- outer.enteredSyms.reverse.foreach(s => captured2(ref(s)))
468
- val tree2 = transform(tree)
469
- capturers --= outer.enteredSyms
470
- seq(captured.result().valuesIterator.toList, tree2)
479
+ if (treeWithoutCaptures == null || ctx.owner.is(Macro )) closure
480
+ else treeWithoutCaptures
471
481
}
472
482
473
483
/** Returns true if this tree will be captured by `makeLambda` */
0 commit comments