@@ -70,6 +70,21 @@ class ReifyQuotes extends MacroTransformWithImplicits {
70
70
private class LevelInfo {
71
71
/** A map from locally defined symbols to the staging levels of their definitions */
72
72
val levelOf = new mutable.HashMap [Symbol , Int ]
73
+
74
+ /** Register a reference defined in a quote but used in another quote nested in a splice.
75
+ * Returns a lifted version of the reference that needs to be used in its place.
76
+ * '{
77
+ * val x = ???
78
+ * { ... '{ ... x ... } ... }.unary_~
79
+ * }
80
+ * Lifting the `x` in `{ ... '{ ... x ... } ... }.unary_~` will return a `x$1.unary_~` for which the `x$1`
81
+ * be created by some outer reifier.
82
+ *
83
+ * This transformation is only applied to definitions at staging level 1.
84
+ *
85
+ * See `needsLifting`
86
+ */
87
+ val lifters = new mutable.HashMap [Symbol , RefTree => Tree ]
73
88
}
74
89
75
90
/** The main transformer class
@@ -354,44 +369,21 @@ class ReifyQuotes extends MacroTransformWithImplicits {
354
369
Closure (meth, tss => body(tss.head.head)(ctx.withOwner(meth)).changeOwner(ctx.owner, meth))
355
370
}
356
371
357
- /** Register a reference defined in a quote but used in another quote nested in a splice.
358
- * Returns a lifted version of the reference that needs to be used in its place.
359
- * '{
360
- * val x = ???
361
- * { ... '{ ... x ... } ... }.unary_~
362
- * }
363
- * Lifting the `x` in `{ ... '{ ... x ... } ... }.unary_~` will return a `x$1.unary_~` for which the `x$1`
364
- * be created by some outer reifier.
365
- *
366
- * This transformation is only applied to definitions at staging level 1.
367
- *
368
- * See `needsLifting`
369
- */
370
- def lift (tree : RefTree )(implicit ctx : Context ): Select =
371
- if (! (level == 0 && outer.enteredSyms.contains(tree.symbol))) outer.lift(tree)
372
- else lifter(tree).select(if (tree.isTerm) nme.UNARY_~ else tpnme.UNARY_~ )
373
- private [this ] var lifter : RefTree => Tree = null
374
-
375
372
private def transformWithLifter (tree : Tree )(
376
373
lifter : mutable.ListBuffer [Tree ] => RefTree => Tree )(implicit ctx : Context ): Tree = {
377
374
val lifted = new mutable.ListBuffer [Tree ]
378
- this .lifter = lifter(lifted)
375
+ val lifter2 = lifter(lifted)
376
+ outer.enteredSyms.foreach(s => lifters.put(s, lifter2))
379
377
val tree2 = transform(tree)
380
- this .lifter = null
378
+ lifters --= outer.enteredSyms
381
379
seq(lifted.result(), tree2)
382
380
}
383
381
384
382
/** Returns true if this tree will be lifted by `makeLambda` */
385
383
private def needsLifting (tree : RefTree )(implicit ctx : Context ): Boolean = {
386
- def isInLiftedTree (reifier : Reifier ): Boolean =
387
- if (reifier.level == 0 ) true
388
- else if (reifier.level == 1 && reifier.enteredSyms.contains(tree.symbol)) false
389
- else isInLiftedTree(reifier.outer)
390
- level == 1 &&
391
- ! tree.symbol.is(Inline ) &&
392
- levelOf.get(tree.symbol).contains(1 ) &&
393
- ! enteredSyms.contains(tree.symbol) &&
394
- isInLiftedTree(outer)
384
+ // Check phase consistency and presence of lifter
385
+ level == 1 && ! tree.symbol.is(Inline ) && levelOf.get(tree.symbol).contains(1 ) &&
386
+ lifters.contains(tree.symbol)
395
387
}
396
388
397
389
/** Transform `tree` and return the resulting tree and all `embedded` quotes
@@ -426,7 +418,8 @@ class ReifyQuotes extends MacroTransformWithImplicits {
426
418
case tree : Select if tree.symbol.isSplice =>
427
419
splice(tree)
428
420
case tree : RefTree if needsLifting(tree) =>
429
- splice(outer.lift(tree))
421
+ val lift = lifters(tree.symbol)
422
+ splice(lift(tree).select(if (tree.isTerm) nme.UNARY_~ else tpnme.UNARY_~ ))
430
423
case Block (stats, _) =>
431
424
val last = enteredSyms
432
425
stats.foreach(markDef)
0 commit comments