@@ -2,7 +2,12 @@ package dotty.tools.dotc
22package transform
33
44import core ._
5- import Decorators ._ , Flags ._ , Types ._ , Contexts ._ , Symbols ._ , Constants ._
5+ import Decorators ._
6+ import Flags ._
7+ import Types ._
8+ import Contexts ._
9+ import Symbols ._
10+ import Constants ._
611import ast .Trees ._
712import ast .{TreeTypeMap , untpd }
813import util .Positions ._
@@ -15,11 +20,12 @@ import typer.Implicits.SearchFailureType
1520import scala .collection .mutable
1621import dotty .tools .dotc .core .StdNames ._
1722import dotty .tools .dotc .core .quoted ._
23+ import dotty .tools .dotc .typer .{ConstFold , Inliner }
1824import dotty .tools .dotc .util .SourcePosition
1925
2026
21- /** Translates quoted terms and types to `unpickle` method calls.
22- * Checks that the phase consistency principle (PCP) holds.
27+ /** Inline calls to inline methods, evaluates macros, translates quoted terms (and types)
28+ * to `unpickle` method calls and checks that the phase consistency principle (PCP) holds.
2329 *
2430 *
2531 * Transforms top level quote
@@ -60,7 +66,7 @@ import dotty.tools.dotc.util.SourcePosition
6066 * The Splicer is used to check that the RHS will be interpretable (with the `Splicer`) once inlined.
6167 */
6268class ReifyQuotes extends MacroTransformWithImplicits {
63- import ast . tpd ._
69+ import tpd ._
6470 import ReifyQuotes ._
6571
6672 /** Classloader used for loading macros */
@@ -88,7 +94,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
8894 }
8995
9096 override def run (implicit ctx : Context ): Unit =
91- if (ctx.compilationUnit.containsQuotesOrSplices) super .run
97+ if (ctx.compilationUnit.containsInlineCalls || ctx.compilationUnit. containsQuotesOrSplices) super .run
9298
9399 protected def newTransformer (implicit ctx : Context ): Transformer =
94100 new Reifier (inQuote = false , null , 0 , new LevelInfo , new Embedded , ctx)
@@ -437,7 +443,8 @@ class ReifyQuotes extends MacroTransformWithImplicits {
437443 else if (enclosingInlineds.nonEmpty) { // level 0 in an inlined call
438444 val spliceCtx = ctx.outer // drop the last `inlineContext`
439445 val pos : SourcePosition = Decorators .sourcePos(enclosingInlineds.head.pos)(spliceCtx)
440- val evaluatedSplice = Splicer .splice(splice.qualifier, pos, macroClassLoader)(spliceCtx).withPos(splice.pos)
446+ val splicedTree = new InlineCalls ().transform(splice.qualifier) // inline calls that where inlined at level -1
447+ val evaluatedSplice = Splicer .splice(splicedTree, pos, macroClassLoader)(spliceCtx).withPos(splice.pos)
441448 if (ctx.reporter.hasErrors) splice else transform(evaluatedSplice)
442449 }
443450 else if (! ctx.owner.isInlineMethod) { // level 0 outside an inline method
@@ -560,6 +567,9 @@ class ReifyQuotes extends MacroTransformWithImplicits {
560567 enteredSyms = enteredSyms.tail
561568 }
562569 tree match {
570+ case tree if isInlineCall(tree) && level == 0 && ! ctx.reporter.hasErrors && ! ctx.settings.YnoInline .value =>
571+ val tree2 = super .transform(tree) // transform arguments before inlining (inline arguments and constant fold arguments)
572+ transform(Inliner .inlineCall(tree2, tree.tpe.widen))
563573 case Quoted (quotedTree) =>
564574 quotation(quotedTree, tree)
565575 case tree : TypeTree if tree.tpe.typeSymbol.isSplice =>
@@ -610,7 +620,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
610620 }
611621 case _ =>
612622 markDef(tree)
613- checkLevel(mapOverTree(enteredSyms))
623+ ConstFold ( checkLevel(mapOverTree(enteredSyms) ))
614624 }
615625 }
616626
@@ -635,6 +645,8 @@ class ReifyQuotes extends MacroTransformWithImplicits {
635645}
636646
637647object ReifyQuotes {
648+ import tpd ._
649+
638650 val name : String = " reifyQuotes"
639651
640652 def toValue (tree : tpd.Tree ): Option [Any ] = tree match {
@@ -664,4 +676,20 @@ object ReifyQuotes {
664676 /** Get the list of embedded trees */
665677 def getTrees : List [tpd.Tree ] = trees.toList
666678 }
679+
680+ /** β-reduce all calls to inline methods and preform constant folding */
681+ class InlineCalls extends TreeMap {
682+ override def transform (tree : Tree )(implicit ctx : Context ): Tree = tree match {
683+ case tree if isInlineCall(tree) && ! ctx.reporter.hasErrors && ! ctx.settings.YnoInline .value =>
684+ val tree2 = super .transform(tree) // transform arguments before inlining (inline arguments and constant fold arguments)
685+ transform(Inliner .inlineCall(tree2, tree.tpe.widen))
686+ case _ : MemberDef =>
687+ val newTree = super .transform(tree)
688+ if (newTree.symbol.exists)
689+ newTree.symbol.defTree = newTree // set for inlined members
690+ newTree
691+ case _ =>
692+ ConstFold (super .transform(tree))
693+ }
694+ }
667695}
0 commit comments