diff --git a/bench/tests/power-macro/PowerInlined-1.scala b/bench/tests/power-macro/PowerInlined-1.scala new file mode 100644 index 000000000000..f0b575d9245a --- /dev/null +++ b/bench/tests/power-macro/PowerInlined-1.scala @@ -0,0 +1,5 @@ +object PowerInlined { + import PowerMacro._ + + power(1, 5.0) // 1 quotes to unpickle +} \ No newline at end of file diff --git a/bench/tests/power-macro/PowerInlined.scala b/bench/tests/power-macro/PowerInlined.scala new file mode 100644 index 000000000000..f0b575d9245a --- /dev/null +++ b/bench/tests/power-macro/PowerInlined.scala @@ -0,0 +1,5 @@ +object PowerInlined { + import PowerMacro._ + + power(1, 5.0) // 1 quotes to unpickle +} \ No newline at end of file diff --git a/bench/tests/power-macro/PowerMacro.scala b/bench/tests/power-macro/PowerMacro.scala new file mode 100644 index 000000000000..31d8f77987d6 --- /dev/null +++ b/bench/tests/power-macro/PowerMacro.scala @@ -0,0 +1,12 @@ +import scala.quoted.Expr + +object PowerMacro { + + inline def power(inline n: Long, x: Double) = ~powerCode(n, '(x)) + + def powerCode(n: Long, x: Expr[Double]): Expr[Double] = + if (n == 0) '(1.0) + else if (n % 2 == 0) '{ { val y = ~x * ~x; ~powerCode(n / 2, '(y)) } } + else '{ ~x * ~powerCode(n - 1, x) } + +} diff --git a/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala b/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala index 89681da9aeaa..293096a2b6e7 100644 --- a/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala +++ b/compiler/src/dotty/tools/dotc/transform/localopt/StringInterpolatorOpt.scala @@ -44,14 +44,12 @@ class StringInterpolatorOpt extends MiniPhase { /** Matches an s or raw string interpolator */ private object SOrRawInterpolator { def unapply(tree: Tree)(implicit ctx: Context): Option[(List[Literal], List[Tree])] = { - if (tree.symbol.eq(defn.StringContextRaw) || tree.symbol.eq(defn.StringContextS)) { - tree match { - case Apply(Select(Apply(StringContextApply(), List(Literals(strs))), _), - List(SeqLiteral(elems, _))) if elems.length == strs.length - 1 => - Some(strs, elems) - case _ => None - } - } else None + tree match { + case Apply(Select(Apply(StringContextApply(), List(Literals(strs))), _), + List(SeqLiteral(elems, _))) if elems.length == strs.length - 1 => + Some(strs, elems) + case _ => None + } } } @@ -82,6 +80,15 @@ class StringInterpolatorOpt extends MiniPhase { } override def transformApply(tree: Apply)(implicit ctx: Context): Tree = { + val sym = tree.symbol + val isInterpolatedMethod = // Test names first to avoid loading scala.StringContext if not used + (sym.name == nme.raw_ && sym.eq(defn.StringContextRaw)) || + (sym.name == nme.s && sym.eq(defn.StringContextS)) + if (isInterpolatedMethod) transformInterpolator(tree) + else tree + } + + private def transformInterpolator(tree: Tree)(implicit ctx: Context): Tree = { tree match { case StringContextIntrinsic(strs: List[Literal], elems: List[Tree]) => val stri = strs.iterator