@@ -103,14 +103,16 @@ class ReifyQuotes extends MacroTransformWithImplicits {
103
103
/** The main transformer class
104
104
* @param inQuote we are within a `'(...)` context that is not shadowed by a nested `~(...)`
105
105
* @param outer the next outer reifier, null is this is the topmost transformer
106
- * @param level the current level, where quotes add one and splices subtract one level
106
+ * @param level the current level, where quotes add one and splices subtract one level.
107
+ * The initial level is 0, a level `l` where `l > 0` implies code has been quotes `l` times
108
+ * and `l == -1` is code inside a top level splice (in an transparent method).
107
109
* @param levels a stacked map from symbols to the levels in which they were defined
108
110
* @param embedded a list of embedded quotes (if `inSplice = true`) or splices (if `inQuote = true`
109
111
*/
110
112
private class Reifier (inQuote : Boolean , val outer : Reifier , val level : Int , levels : LevelInfo ,
111
113
val embedded : mutable.ListBuffer [Tree ]) extends ImplicitsTransformer {
112
114
import levels ._
113
- assert(level >= 0 )
115
+ assert(level >= - 1 )
114
116
115
117
/** A nested reifier for a quote (if `isQuote = true`) or a splice (if not) */
116
118
def nested (isQuote : Boolean ): Reifier = {
@@ -205,7 +207,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
205
207
}
206
208
207
209
/** Enter staging level of symbol defined by `tree`, if applicable. */
208
- def markDef (tree : Tree )(implicit ctx : Context ) = tree match {
210
+ def markDef (tree : Tree )(implicit ctx : Context ): Unit = tree match {
209
211
case tree : DefTree =>
210
212
val sym = tree.symbol
211
213
if ((sym.isClass || ! sym.maybeOwner.isType) && ! levelOf.contains(sym)) {
@@ -223,7 +225,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
223
225
def levelOK (sym : Symbol )(implicit ctx : Context ): Boolean = levelOf.get(sym) match {
224
226
case Some (l) =>
225
227
l == level ||
226
- l == 1 && level == 0 && isStage0Value (sym)
228
+ l == 0 && level == - 1 && isStageNegOneValue (sym)
227
229
case None =>
228
230
! sym.is(Param ) || levelOK(sym.owner)
229
231
}
@@ -239,7 +241,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
239
241
*/
240
242
def tryHeal (tp : Type , pos : Position )(implicit ctx : Context ): Option [String ] = tp match {
241
243
case tp : TypeRef =>
242
- if (level == 0 ) {
244
+ if (level == - 1 ) {
243
245
assert(ctx.owner.ownersIterator.exists(_.is(Transparent )))
244
246
None
245
247
} else {
@@ -357,7 +359,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
357
359
}
358
360
else body match {
359
361
case body : RefTree if isCaptured(body.symbol, level + 1 ) =>
360
- if (isStage0Value (body.symbol)) {
362
+ if (isStageNegOneValue (body.symbol)) {
361
363
// Optimization: avoid the full conversion when capturing inlined `x`
362
364
// in '{ x } to '{ x$1.toExpr.unary_~ } and go directly to `x$1.toExpr`
363
365
liftInlineParamValue(capturers(body.symbol)(body))
@@ -368,7 +370,11 @@ class ReifyQuotes extends MacroTransformWithImplicits {
368
370
}
369
371
case _=>
370
372
val (body1, splices) = nested(isQuote = true ).split(body)
371
- pickledQuote(body1, splices, body.tpe, isType).withPos(quote.pos)
373
+ if (level >= 0 ) pickledQuote(body1, splices, body.tpe, isType).withPos(quote.pos)
374
+ else {
375
+ // In top-level splice in an transparent def. Keep the tree as it is, it will be transformed at inline site.
376
+ body
377
+ }
372
378
}
373
379
}
374
380
@@ -412,7 +418,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
412
418
val body1 = nested(isQuote = false ).transform(splice.qualifier)
413
419
body1.select(splice.name)
414
420
}
415
- else if (! inQuote && level == 0 ) {
421
+ else if (! inQuote && level == 0 && ! ctx.owner.is( Transparent ) ) {
416
422
spliceOutsideQuotes(splice.pos)
417
423
splice
418
424
}
@@ -458,7 +464,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
458
464
val tpw = tree.tpe.widen
459
465
val argTpe =
460
466
if (tree.isType) defn.QuotedTypeType .appliedTo(tpw)
461
- else if (isStage0Value (tree.symbol)) tpw
467
+ else if (isStageNegOneValue (tree.symbol)) tpw
462
468
else defn.QuotedExprType .appliedTo(tpw)
463
469
val selectArg = arg.select(nme.apply).appliedTo(Literal (Constant (i))).asInstance(argTpe)
464
470
val capturedArg = SyntheticValDef (UniqueName .fresh(tree.symbol.name.toTermName).toTermName, selectArg)
@@ -495,7 +501,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
495
501
private def isCaptured (sym : Symbol , level : Int )(implicit ctx : Context ): Boolean = {
496
502
// Check phase consistency and presence of capturer
497
503
( (level == 1 && levelOf.get(sym).contains(1 )) ||
498
- (level == 0 && isStage0Value (sym))
504
+ (level == 0 && isStageNegOneValue (sym))
499
505
) && capturers.contains(sym)
500
506
}
501
507
@@ -537,7 +543,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
537
543
val capturer = capturers(tree.symbol)
538
544
def captureAndSplice (t : Tree ) =
539
545
splice(t.select(if (tree.isTerm) nme.UNARY_~ else tpnme.UNARY_~ ))
540
- if (! isStage0Value (tree.symbol)) captureAndSplice(capturer(tree))
546
+ if (! isStageNegOneValue (tree.symbol)) captureAndSplice(capturer(tree))
541
547
else if (level == 0 ) capturer(tree)
542
548
else captureAndSplice(liftInlineParamValue(capturer(tree)))
543
549
case Block (stats, _) =>
@@ -559,13 +565,12 @@ class ReifyQuotes extends MacroTransformWithImplicits {
559
565
case _ : Import =>
560
566
tree
561
567
case tree : DefDef if tree.symbol.is(Macro ) && level == 0 =>
568
+ markDef(tree)
562
569
tree.rhs match {
563
570
case InlineSplice (_) =>
564
571
if (! tree.symbol.isStatic)
565
572
ctx.error(" Transparent macro method must be a static method." , tree.pos)
566
- markDef(tree)
567
- val reifier = nested(isQuote = true )
568
- reifier.transform(tree) // Ignore output, only check PCP
573
+ mapOverTree(enteredSyms) // Ignore output, only check PCP
569
574
cpy.DefDef (tree)(rhs = defaultValue(tree.rhs.tpe))
570
575
case _ =>
571
576
ctx.error(
@@ -602,7 +607,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
602
607
ref(lifter).select(" toExpr" .toTermName).appliedTo(tree)
603
608
}
604
609
605
- private def isStage0Value (sym : Symbol )(implicit ctx : Context ): Boolean =
610
+ private def isStageNegOneValue (sym : Symbol )(implicit ctx : Context ): Boolean =
606
611
(sym.is(Transparent ) && sym.owner.is(Transparent ) && ! defn.isFunctionType(sym.info)) ||
607
612
sym == defn.TastyTopLevelSplice_tastyContext // intrinsic value at stage 0
608
613
0 commit comments