Skip to content

Commit 6c7ac49

Browse files
committed
Fix #3898: Do not interpret bindings for inlined parameters
1 parent 3365ed3 commit 6c7ac49

File tree

9 files changed

+43
-5
lines changed

9 files changed

+43
-5
lines changed

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

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -322,10 +322,19 @@ 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+
if (level == 0) {
326+
// To maintain phase consistency, we move the binding of the this parameter into the spliced code
327+
val (thisBindings, otherBindings) = bindings.partition {
328+
case vdef: ValDef => vdef.symbol.is(Synthetic) // Assume that only _this bindings are tagged with Synthetic
329+
case _ => false
330+
}
331+
val splicedBody = Splicer.splice(seq(thisBindings, body))
332+
transform(cpy.Inlined(tree)(call, otherBindings, splicedBody))
333+
} else {
334+
// To maintain phase consistency, convert inlined expressions of the form
335+
// `{ bindings; ~expansion }` to `~{ bindings; expansion }`
336+
transform(cpy.Select(expansion)(cpy.Inlined(tree)(call, bindings, body), name))
337+
}
329338
case _: Import =>
330339
tree
331340
case tree: DefDef if tree.symbol.is(Macro) && level == 0 =>

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

Lines changed: 1 addition & 0 deletions
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

Lines changed: 1 addition & 1 deletion
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 6 additions & 0 deletions
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

Lines changed: 5 additions & 0 deletions
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

Lines changed: 6 additions & 0 deletions
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/quote-interpolator-core/quoted_1.scala

Lines changed: 3 additions & 0 deletions
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

Lines changed: 3 additions & 0 deletions
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)