@@ -66,16 +66,19 @@ import dotty.tools.dotc.core.quoted._
6666 * ```
6767 * to
6868 * ```
69- * inline def foo[T1, ...](inline x1: X, ..., y1: Y, .... ): Seq[Any] => Object = { (args: Seq[Any]) => {
69+ * inline def foo[T1, ...](inline x1: X, ..., y1: Y, ..., inline f1: X => Y ): Seq[Any] => Object = { (args: Seq[Any]) => {
7070 * val T1$1 = args(0).asInstanceOf[Type[T1]]
7171 * ...
7272 * val x1$1 = args(0).asInstanceOf[X]
7373 * ...
7474 * val y1$1 = args(1).asInstanceOf[Expr[Y]]
7575 * ...
76- * { ... x1$1 .... '{ ... T1$1.unary_~ ... x1$1.toExpr.unary_~ ... y1$1.unary_~ ... } ... }
76+ * { ... x1$1 .... '{ ... T1$1.unary_~ ... x1$1.toExpr.unary_~ ... y1$1.unary_~ ... f1$1.unary_~ ... } ... }
7777 * }
7878 * ```
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`.
81+ *
7982 * Note: the parameters of `foo` are kept for simple overloading resolution but they are not used in the body of `foo`.
8083 *
8184 * At inline site we will call reflectively the static method `foo` with dummy parameters, which will return a
@@ -243,7 +246,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
243246 def levelOK (sym : Symbol )(implicit ctx : Context ): Boolean = levelOf.get(sym) match {
244247 case Some (l) =>
245248 l == level ||
246- sym.is( Inline ) && sym.owner.is( Macro ) && sym.info.isValueType && l - 1 == level
249+ l == 1 && level == 0 && isStage0Value(sym)
247250 case None =>
248251 ! sym.is(Param ) || levelOK(sym.owner)
249252 }
@@ -374,8 +377,8 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
374377 else ref(defn.QuotedExpr_apply ).appliedToType(body1.tpe.widen).appliedTo(body1)
375378 }
376379 else body match {
377- case body : RefTree if isCaptured(body, level + 1 ) =>
378- if (body.symbol.is( Inline )) {
380+ case body : RefTree if isCaptured(body.symbol , level + 1 ) =>
381+ if (isStage0Value( body.symbol)) {
379382 // Optimization: avoid the full conversion when capturing inlined `x`
380383 // in '{ x } to '{ x$1.toExpr.unary_~ } and go directly to `x$1.toExpr`
381384 liftValue(capturers(body.symbol)(body))
@@ -476,7 +479,7 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
476479 val tpw = tree.tpe.widen
477480 val argTpe =
478481 if (tree.isType) defn.QuotedTypeType .appliedTo(tpw)
479- else if (tree.symbol.is( Inline )) tpw // inlined term
482+ else if (isStage0Value( tree.symbol)) tpw
480483 else defn.QuotedExprType .appliedTo(tpw)
481484 val selectArg = arg.select(nme.apply).appliedTo(Literal (Constant (i))).asInstance(argTpe)
482485 val capturedArg = SyntheticValDef (UniqueName .fresh(tree.symbol.name.toTermName).toTermName, selectArg)
@@ -509,11 +512,11 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
509512 }
510513
511514 /** Returns true if this tree will be captured by `makeLambda` */
512- private def isCaptured (tree : RefTree , level : Int )(implicit ctx : Context ): Boolean = {
515+ private def isCaptured (sym : Symbol , level : Int )(implicit ctx : Context ): Boolean = {
513516 // Check phase consistency and presence of capturer
514- ( (level == 1 && levelOf.get(tree.symbol ).contains(1 )) ||
515- (level == 0 && tree.symbol.is( Inline ))
516- ) && capturers.contains(tree.symbol )
517+ ( (level == 1 && levelOf.get(sym ).contains(1 )) ||
518+ (level == 0 && isStage0Value(sym ))
519+ ) && capturers.contains(sym )
517520 }
518521
519522 /** Transform `tree` and return the resulting tree and all `embedded` quotes
@@ -550,13 +553,13 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
550553 splice(ref(splicedType).select(tpnme.UNARY_~ ))
551554 case tree : Select if tree.symbol.isSplice =>
552555 splice(tree)
553- case tree : RefTree if isCaptured(tree, level) =>
556+ case tree : RefTree if isCaptured(tree.symbol , level) =>
554557 val capturer = capturers(tree.symbol)
555558 def captureAndSplice (t : Tree ) =
556559 splice(t.select(if (tree.isTerm) nme.UNARY_~ else tpnme.UNARY_~ ))
557- if (tree.symbol.is( Inline ) && level == 0 ) capturer(tree)
558- else if (tree.symbol.is( Inline )) captureAndSplice(liftValue( capturer(tree)) )
559- else captureAndSplice(capturer(tree))
560+ if (! isStage0Value( tree.symbol)) captureAndSplice( capturer(tree) )
561+ else if (level == 0 ) capturer(tree)
562+ else captureAndSplice(liftValue( capturer(tree) ))
560563 case Block (stats, _) =>
561564 val last = enteredSyms
562565 stats.foreach(markDef)
@@ -604,10 +607,6 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
604607 """ .stripMargin, tree.rhs.pos)
605608 EmptyTree
606609 }
607- case tree : ValDef if tree.symbol.is(Param | Inline ) && tree.symbol.owner.is(Macro ) &&
608- defn.isFunctionClass(tree.tpe.widen.typeSymbol) =>
609- ctx.error(" Macro parameters of function type cannot be `inline`" , tree.pos)
610- EmptyTree
611610 case _ =>
612611 markDef(tree)
613612 checkLevel(mapOverTree(enteredSyms))
@@ -629,6 +628,9 @@ class ReifyQuotes extends MacroTransformWithImplicits with InfoTransformer {
629628 }
630629 }
631630
631+ private def isStage0Value (sym : Symbol )(implicit ctx : Context ): Boolean =
632+ sym.is(Inline ) && sym.owner.is(Macro ) && ! defn.isFunctionType(sym.info)
633+
632634 private def liftList (list : List [Tree ], tpe : Type )(implicit ctx : Context ): Tree = {
633635 list.foldRight[Tree ](ref(defn.NilModule )) { (x, acc) =>
634636 acc.select(" ::" .toTermName).appliedToType(tpe).appliedTo(x)
0 commit comments