@@ -7,13 +7,10 @@ import Flags._
7
7
import ast .Trees ._
8
8
import ast .{TreeTypeMap , untpd }
9
9
import util .Positions ._
10
- import StdNames ._
11
10
import tasty .TreePickler .Hole
12
- import MegaPhase .MiniPhase
13
11
import SymUtils ._
14
12
import NameKinds ._
15
13
import dotty .tools .dotc .ast .tpd .Tree
16
- import dotty .tools .dotc .core .DenotTransformers .InfoTransformer
17
14
import typer .Implicits .SearchFailureType
18
15
19
16
import scala .collection .mutable
@@ -60,33 +57,9 @@ import dotty.tools.dotc.core.quoted._
60
57
*
61
58
*
62
59
* 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.
88
61
*/
89
- class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
62
+ class ReifyQuotes extends MacroTransformWithImplicits {
90
63
import ast .tpd ._
91
64
92
65
/** Classloader used for loading macros */
@@ -582,16 +555,12 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
582
555
val last = enteredSyms
583
556
stats.foreach(markDef)
584
557
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)) =>
587
559
val tree2 =
588
560
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)
593
562
if (ctx.reporter.hasErrors) EmptyTree
594
- else transform(cpy.Inlined (tree)(call2 , bindings, spliced ))
563
+ else transform(cpy.Inlined (tree)(call , bindings, evaluatedSplice ))
595
564
}
596
565
else super .transform(tree)
597
566
@@ -607,22 +576,14 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
607
576
ctx.error(" Inline macro method must be a static method." , tree.pos)
608
577
markDef(tree)
609
578
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))
615
581
case _ =>
616
582
ctx.error(
617
583
""" Malformed inline macro.
618
584
|
619
585
|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))
626
587
""" .stripMargin, tree.rhs.pos)
627
588
EmptyTree
628
589
}
@@ -664,38 +625,16 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
664
625
* consists of a (possibly multiple & nested) block or a sole expression.
665
626
*/
666
627
object InlineSplice {
667
- def unapply (tree : Tree )(implicit ctx : Context ): Option [Select ] = {
628
+ def unapply (tree : Tree )(implicit ctx : Context ): Option [Tree ] = {
668
629
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 )
670
631
case Block (List (stat), Literal (Constant (()))) => unapply(stat)
671
632
case Block (Nil , expr) => unapply(expr)
672
633
case _ => None
673
634
}
674
635
}
675
636
}
676
637
}
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 )
699
638
}
700
639
701
640
object ReifyQuotes {
0 commit comments