Skip to content

Commit 7f47b9d

Browse files
Merge pull request #4019 from dotty-staging/fix-#3898
Fix #3898: Do not interpret bindings for inlined parameters
2 parents 4149833 + 5b54dd0 commit 7f47b9d

File tree

11 files changed

+53
-5
lines changed

11 files changed

+53
-5
lines changed

compiler/src/dotty/tools/dotc/transform/ReifyQuotes.scala

+9-4
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,15 @@ class ReifyQuotes extends MacroTransformWithImplicits {
322322
stats.foreach(markDef)
323323
mapOverTree(last)
324324
case Inlined(call, bindings, expansion @ Select(body, name)) if expansion.symbol.isSplice =>
325-
// To maintain phase consistency, convert inlined expressions of the form
326-
// `{ bindings; ~expansion }` to `~{ bindings; expansion }`
327-
if (level == 0) transform(Splicer.splice(cpy.Inlined(tree)(call, bindings, body)))
328-
else transform(cpy.Select(expansion)(cpy.Inlined(tree)(call, bindings, body), name))
325+
// To maintain phase consistency, we move the binding of the this parameter into the spliced code
326+
val (splicedBindings, stagedBindings) = bindings.partition {
327+
case vdef: ValDef => vdef.symbol.is(Synthetic) // Assume that only _this bindings are tagged with Synthetic
328+
case _ => false
329+
}
330+
val tree1 =
331+
if (level == 0) cpy.Inlined(tree)(call, stagedBindings, Splicer.splice(seq(splicedBindings, body)))
332+
else seq(stagedBindings, cpy.Select(expansion)(cpy.Inlined(tree)(call, splicedBindings, body), name))
333+
transform(tree1)
329334
case _: Import =>
330335
tree
331336
case tree: DefDef if tree.symbol.is(Macro) && level == 0 =>

compiler/src/dotty/tools/dotc/transform/Splicer.scala

+1
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ object Splicer {
1919
case tree: RefTree => reflectiveSplice(tree)
2020
case tree: Apply => reflectiveSplice(tree)
2121
case tree: Inlined => reflectiveSplice(tree)
22+
case tree: Block => reflectiveSplice(tree)
2223
}
2324

2425
/** Splice the Tree for a Quoted expression which is constructed via a reflective call to the given method */

compiler/src/dotty/tools/dotc/typer/Inliner.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ class Inliner(call: tpd.Tree, rhs: tpd.Tree)(implicit ctx: Context) {
394394
case tpe: ThisType if !canElideThis(tpe) && !thisProxy.contains(tpe.cls) =>
395395
val proxyName = s"${tpe.cls.name}_this".toTermName
396396
val proxyType = tpe.asSeenFrom(prefix.tpe, meth.owner)
397-
thisProxy(tpe.cls) = newSym(proxyName, EmptyFlags, proxyType).termRef
397+
thisProxy(tpe.cls) = newSym(proxyName, Synthetic, proxyType).termRef
398398
if (!tpe.cls.isStaticOwner)
399399
registerType(meth.owner.thisType) // make sure we have a base from which to outer-select
400400
case tpe: NamedType

tests/pos/i3898/quoted_1.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import scala.quoted._
2+
object Macro {
3+
inline def ff(args: Any*): String = ~impl('(args))
4+
def impl(args: Expr[Seq[Any]]): Expr[String] = ""
5+
}

tests/pos/i3898/quoted_2.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
def x: Int = 5
4+
Macro.ff(x)
5+
}
6+
}

tests/pos/i3898b/quoted_1.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import scala.quoted._
2+
object Macro {
3+
inline def ff(x: Int, inline y: Int): String = ~impl('(x))
4+
def impl(x: Expr[Int]): Expr[String] = ""
5+
}

tests/pos/i3898b/quoted_2.scala

+6
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
def z: Int = 5
4+
Macro.ff(z, 5)
5+
}
6+
}

tests/pos/i3898c/quoted_1.scala

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
import scala.quoted._
2+
object Macro {
3+
inline def ff(x: Int, inline y: Int): String = ~impl('(x))
4+
def impl(x: Expr[Int]): Expr[String] = ""
5+
}

tests/pos/i3898c/quoted_2.scala

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
object Test {
2+
def main(args: Array[String]): Unit = {
3+
val a = '{
4+
def z: Int = 5
5+
Macro.ff(z, 5)
6+
}
7+
8+
}
9+
}

tests/pos/quote-interpolator-core/quoted_1.scala

+3
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,7 @@ object FInterpolation {
2121
val args1: Expr[Seq[Any]] = liftSeq(args)
2222
'{ (~str).format(~args1: _*) }
2323
}
24+
25+
def hello = "hello"
26+
2427
}

tests/pos/quote-interpolator-core/quoted_2.scala

+3
Original file line numberDiff line numberDiff line change
@@ -5,4 +5,7 @@ object Test {
55
println(ff"integer: ${5}%d")
66
println(ff"string: ${"l"}%s")
77
println(ff"${5}%s, ${6}%d, ${"hello"}%s")
8+
val hello = "hello"
9+
println(ff"${5}%s, ${6}%d, ${hello}%s")
10+
println(ff"${5}%s, ${6}%d, ${FInterpolation.hello}%s")
811
}

0 commit comments

Comments
 (0)