@@ -7,13 +7,10 @@ import Flags._
77import ast .Trees ._
88import ast .{TreeTypeMap , untpd }
99import util .Positions ._
10- import StdNames ._
1110import tasty .TreePickler .Hole
12- import MegaPhase .MiniPhase
1311import SymUtils ._
1412import NameKinds ._
1513import dotty .tools .dotc .ast .tpd .Tree
16- import dotty .tools .dotc .core .DenotTransformers .InfoTransformer
1714import typer .Implicits .SearchFailureType
1815
1916import scala .collection .mutable
@@ -60,33 +57,9 @@ import dotty.tools.dotc.core.quoted._
6057 *
6158 *
6259 * For inline macro definitions we assume that we have a single ~ directly as the RHS.
63- * We will transform the definition from
64- * ```
65- * inline def foo[T1, ...](inline x1: X, ..., y1: Y, ....): Z = ~{ ... T1 ... x ... '(y) ... }
66- * ```
67- * to
68- * ```
69- * inline def foo[T1, ...](inline x1: X, ..., y1: Y, ....): Seq[Any] => Object = { (args: Seq[Any]) => {
70- * val T1$1 = args(0).asInstanceOf[Type[T1]]
71- * ...
72- * val x1$1 = args(0).asInstanceOf[X]
73- * ...
74- * val y1$1 = args(1).asInstanceOf[Expr[Y]]
75- * ...
76- * { ... x1$1 .... '{ ... T1$1.unary_~ ... x1$1.toExpr.unary_~ ... y1$1.unary_~ ... } ... }
77- * }
78- * ```
79- * Where `inline` parameters with type Boolean, Byte, Short, Int, Long, Float, Double, Char and String are
80- * passed as their actual runtime value. See `isStage0Value`. Other `inline` arguments such as functions are handled
81- * like `y1: Y`.
82- *
83- * Note: the parameters of `foo` are kept for simple overloading resolution but they are not used in the body of `foo`.
84- *
85- * At inline site we will call reflectively the static method `foo` with dummy parameters, which will return a
86- * precompiled version of the function that will evaluate the `Expr[Z]` that `foo` produces. The lambda is then called
87- * at the inline site with the lifted arguments of the inlined call.
60+ * The Splicer is used to check that the RHS will be interpretable (with the `Splicer`) once inlined.
8861 */
89- class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
62+ class ReifyQuotes extends MacroTransformWithImplicits {
9063 import ast .tpd ._
9164
9265 /** Classloader used for loading macros */
@@ -582,16 +555,12 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
582555 val last = enteredSyms
583556 stats.foreach(markDef)
584557 mapOverTree(last)
585- case Inlined (call, bindings, InlineSplice (expansion @ Select (body, name))) =>
586- assert(call.symbol.is(Macro ))
558+ case Inlined (call, bindings, InlineSplice (spliced)) =>
587559 val tree2 =
588560 if (level == 0 ) {
589- // Simplification of the call done in PostTyper for non-macros can also be performed now
590- // see PostTyper `case Inlined(...) =>` for description of the simplification
591- val call2 = Ident (call.symbol.topLevelClass.typeRef).withPos(call.pos)
592- val spliced = Splicer .splice(body, call, bindings, tree.pos, macroClassLoader).withPos(tree.pos)
561+ val evaluatedSplice = Splicer .splice(spliced, tree.pos, macroClassLoader).withPos(tree.pos)
593562 if (ctx.reporter.hasErrors) EmptyTree
594- else transform(cpy.Inlined (tree)(call2 , bindings, spliced ))
563+ else transform(cpy.Inlined (tree)(call , bindings, evaluatedSplice ))
595564 }
596565 else super .transform(tree)
597566
@@ -607,22 +576,14 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
607576 ctx.error(" Inline macro method must be a static method." , tree.pos)
608577 markDef(tree)
609578 val reifier = nested(isQuote = true )
610- reifier.transform(tree) // Ignore output, we only need the its embedding
611- assert(reifier.embedded.size == 1 )
612- val lambda = reifier.embedded.head
613- // replace macro code by lambda used to evaluate the macro expansion
614- cpy.DefDef (tree)(tpt = TypeTree (macroReturnType), rhs = lambda)
579+ reifier.transform(tree) // Ignore output, only check PCP
580+ cpy.DefDef (tree)(rhs = defaultValue(tree.rhs.tpe))
615581 case _ =>
616582 ctx.error(
617583 """ Malformed inline macro.
618584 |
619585 |Expected the ~ to be at the top of the RHS:
620- | inline def foo(...): Int = ~impl(...)
621- |or
622- | inline def foo(...): Int = ~{
623- | val x = 1
624- | impl(... x ...)
625- | }
586+ | inline def foo(x: X, ..., y: Y): Int = ~impl(x, ... '(y))
626587 """ .stripMargin, tree.rhs.pos)
627588 EmptyTree
628589 }
@@ -664,38 +625,16 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
664625 * consists of a (possibly multiple & nested) block or a sole expression.
665626 */
666627 object InlineSplice {
667- def unapply (tree : Tree )(implicit ctx : Context ): Option [Select ] = {
628+ def unapply (tree : Tree )(implicit ctx : Context ): Option [Tree ] = {
668629 tree match {
669- case expansion : Select if expansion .symbol.isSplice => Some (expansion )
630+ case Select (qual, _) if tree .symbol.isSplice && Splicer .canBeSpliced(qual) => Some (qual )
670631 case Block (List (stat), Literal (Constant (()))) => unapply(stat)
671632 case Block (Nil , expr) => unapply(expr)
672633 case _ => None
673634 }
674635 }
675636 }
676637 }
677-
678- def transformInfo (tp : Type , sym : Symbol )(implicit ctx : Context ): Type = {
679- /** Transforms the return type of
680- * inline def foo(...): X = ~(...)
681- * to
682- * inline def foo(...): Seq[Any] => Expr[Any] = (args: Seq[Any]) => ...
683- */
684- def transform (tp : Type ): Type = tp match {
685- case tp : MethodType => MethodType (tp.paramNames, tp.paramInfos, transform(tp.resType))
686- case tp : PolyType => PolyType (tp.paramNames, tp.paramInfos, transform(tp.resType))
687- case tp : ExprType => ExprType (transform(tp.resType))
688- case _ => macroReturnType
689- }
690- transform(tp)
691- }
692-
693- override protected def mayChange (sym : Symbol )(implicit ctx : Context ): Boolean =
694- ctx.compilationUnit.containsQuotesOrSplices && sym.isTerm && sym.is(Macro )
695-
696- /** Returns the type of the compiled macro as a lambda: Seq[Any] => Object */
697- private def macroReturnType (implicit ctx : Context ): Type =
698- defn.FunctionType (1 ).appliedTo(defn.SeqType .appliedTo(defn.AnyType ), defn.ObjectType )
699638}
700639
701640object ReifyQuotes {
0 commit comments