@@ -103,14 +103,16 @@ class ReifyQuotes extends MacroTransformWithImplicits {
103103 /** The main transformer class
104104 * @param inQuote we are within a `'(...)` context that is not shadowed by a nested `~(...)`
105105 * @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 quoted `l` times
108+ * and `l == -1` is code inside a top level splice (in an transparent method).
107109 * @param levels a stacked map from symbols to the levels in which they were defined
108110 * @param embedded a list of embedded quotes (if `inSplice = true`) or splices (if `inQuote = true`
109111 */
110112 private class Reifier (inQuote : Boolean , val outer : Reifier , val level : Int , levels : LevelInfo ,
111113 val embedded : mutable.ListBuffer [Tree ]) extends ImplicitsTransformer {
112114 import levels ._
113- assert(level >= 0 )
115+ assert(level >= - 1 )
114116
115117 /** A nested reifier for a quote (if `isQuote = true`) or a splice (if not) */
116118 def nested (isQuote : Boolean ): Reifier = {
@@ -205,7 +207,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
205207 }
206208
207209 /** 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 {
209211 case tree : DefTree =>
210212 val sym = tree.symbol
211213 if ((sym.isClass || ! sym.maybeOwner.isType) && ! levelOf.contains(sym)) {
@@ -223,7 +225,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
223225 def levelOK (sym : Symbol )(implicit ctx : Context ): Boolean = levelOf.get(sym) match {
224226 case Some (l) =>
225227 l == level ||
226- l == 1 && level == 0 && isStage0Value (sym)
228+ l == 0 && level == - 1 && isStageNegOneValue (sym)
227229 case None =>
228230 ! sym.is(Param ) || levelOK(sym.owner)
229231 }
@@ -239,7 +241,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
239241 */
240242 def tryHeal (tp : Type , pos : Position )(implicit ctx : Context ): Option [String ] = tp match {
241243 case tp : TypeRef =>
242- if (level == 0 ) {
244+ if (level == - 1 ) {
243245 assert(ctx.owner.ownersIterator.exists(_.is(Transparent )))
244246 None
245247 } else {
@@ -357,7 +359,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
357359 }
358360 else body match {
359361 case body : RefTree if isCaptured(body.symbol, level + 1 ) =>
360- if (isStage0Value (body.symbol)) {
362+ if (isStageNegOneValue (body.symbol)) {
361363 // Optimization: avoid the full conversion when capturing inlined `x`
362364 // in '{ x } to '{ x$1.toExpr.unary_~ } and go directly to `x$1.toExpr`
363365 liftInlineParamValue(capturers(body.symbol)(body))
@@ -368,7 +370,11 @@ class ReifyQuotes extends MacroTransformWithImplicits {
368370 }
369371 case _=>
370372 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+ }
372378 }
373379 }
374380
@@ -412,7 +418,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
412418 val body1 = nested(isQuote = false ).transform(splice.qualifier)
413419 body1.select(splice.name)
414420 }
415- else if (! inQuote && level == 0 ) {
421+ else if (! inQuote && level == 0 && ! ctx.owner.is( Transparent ) ) {
416422 spliceOutsideQuotes(splice.pos)
417423 splice
418424 }
@@ -458,7 +464,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
458464 val tpw = tree.tpe.widen
459465 val argTpe =
460466 if (tree.isType) defn.QuotedTypeType .appliedTo(tpw)
461- else if (isStage0Value (tree.symbol)) tpw
467+ else if (isStageNegOneValue (tree.symbol)) tpw
462468 else defn.QuotedExprType .appliedTo(tpw)
463469 val selectArg = arg.select(nme.apply).appliedTo(Literal (Constant (i))).asInstance(argTpe)
464470 val capturedArg = SyntheticValDef (UniqueName .fresh(tree.symbol.name.toTermName).toTermName, selectArg)
@@ -495,7 +501,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
495501 private def isCaptured (sym : Symbol , level : Int )(implicit ctx : Context ): Boolean = {
496502 // Check phase consistency and presence of capturer
497503 ( (level == 1 && levelOf.get(sym).contains(1 )) ||
498- (level == 0 && isStage0Value (sym))
504+ (level == 0 && isStageNegOneValue (sym))
499505 ) && capturers.contains(sym)
500506 }
501507
@@ -537,7 +543,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
537543 val capturer = capturers(tree.symbol)
538544 def captureAndSplice (t : Tree ) =
539545 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))
541547 else if (level == 0 ) capturer(tree)
542548 else captureAndSplice(liftInlineParamValue(capturer(tree)))
543549 case Block (stats, _) =>
@@ -559,13 +565,12 @@ class ReifyQuotes extends MacroTransformWithImplicits {
559565 case _ : Import =>
560566 tree
561567 case tree : DefDef if tree.symbol.is(Macro ) && level == 0 =>
568+ if (enclosingInlineds.nonEmpty)
569+ return EmptyTree // Already checked at definition site and already inlined
570+ markDef(tree)
562571 tree.rhs match {
563572 case InlineSplice (_) =>
564- if (! tree.symbol.isStatic)
565- 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
569574 cpy.DefDef (tree)(rhs = defaultValue(tree.rhs.tpe))
570575 case _ =>
571576 ctx.error(
@@ -602,7 +607,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
602607 ref(lifter).select(" toExpr" .toTermName).appliedTo(tree)
603608 }
604609
605- private def isStage0Value (sym : Symbol )(implicit ctx : Context ): Boolean =
610+ private def isStageNegOneValue (sym : Symbol )(implicit ctx : Context ): Boolean =
606611 (sym.is(Transparent ) && sym.owner.is(Transparent ) && ! defn.isFunctionType(sym.info)) ||
607612 sym == defn.TastyTopLevelSplice_tastyContext // intrinsic value at stage 0
608613
0 commit comments