Skip to content

Commit c559d73

Browse files
Merge pull request #5153 from dotty-staging/fix-#5152
Fix #5152: Use context of the target location
2 parents 0673829 + f1a37dd commit c559d73

File tree

3 files changed

+31
-5
lines changed

3 files changed

+31
-5
lines changed

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

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -90,7 +90,7 @@ class ReifyQuotes extends MacroTransformWithImplicits {
9090
if (ctx.compilationUnit.containsQuotesOrSplices) super.run
9191

9292
protected def newTransformer(implicit ctx: Context): Transformer =
93-
new Reifier(inQuote = false, null, 0, new LevelInfo, new mutable.ListBuffer[Tree])
93+
new Reifier(inQuote = false, null, 0, new LevelInfo, new mutable.ListBuffer, ctx)
9494

9595
private class LevelInfo {
9696
/** A map from locally defined symbols to the staging levels of their definitions */
@@ -120,16 +120,17 @@ class ReifyQuotes extends MacroTransformWithImplicits {
120120
* and `l == -1` is code inside a top level splice (in an inline method).
121121
* @param levels a stacked map from symbols to the levels in which they were defined
122122
* @param embedded a list of embedded quotes (if `inSplice = true`) or splices (if `inQuote = true`
123+
* @param rctx the contex in the destination lifted lambda
123124
*/
124125
private class Reifier(inQuote: Boolean, val outer: Reifier, val level: Int, levels: LevelInfo,
125-
val embedded: mutable.ListBuffer[Tree]) extends ImplicitsTransformer {
126+
val embedded: mutable.ListBuffer[Tree], val rctx: Context) extends ImplicitsTransformer {
126127
import levels._
127128
assert(level >= -1)
128129

129130
/** A nested reifier for a quote (if `isQuote = true`) or a splice (if not) */
130-
def nested(isQuote: Boolean): Reifier = {
131+
def nested(isQuote: Boolean)(implicit ctx: Context): Reifier = {
131132
val nestedEmbedded = if (level > 1 || (level == 1 && isQuote)) embedded else new mutable.ListBuffer[Tree]
132-
new Reifier(isQuote, this, if (isQuote) level + 1 else level - 1, levels, nestedEmbedded)
133+
new Reifier(isQuote, this, if (isQuote) level + 1 else level - 1, levels, nestedEmbedded, ctx)
133134
}
134135

135136
/** We are in a `~(...)` context that is not shadowed by a nested `'(...)` */
@@ -493,8 +494,12 @@ class ReifyQuotes extends MacroTransformWithImplicits {
493494
}
494495
)
495496
}
497+
/* Lambdas are generated outside the quote that is beeing reified (i.e. in outer.rctx.owner).
498+
* In case the case that level == -1 the code is not in a quote, it is in an inline method,
499+
* hence we should take that as owner directly.
500+
*/
501+
val lambdaOwner = if (level == -1) ctx.owner else outer.rctx.owner
496502

497-
val lambdaOwner = ctx.owner.ownersIterator.find(o => levelOf.getOrElse(o, level) == level).get
498503
val tpe = MethodType(defn.SeqType.appliedTo(defn.AnyType) :: Nil, tree.tpe.widen)
499504
val meth = ctx.newSymbol(lambdaOwner, UniqueName.fresh(nme.ANON_FUN), Synthetic | Method, tpe)
500505
Closure(meth, tss => body(tss.head.head)(ctx.withOwner(meth)).changeOwner(ctx.owner, meth))

tests/run-with-compiler/i5152.check

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
{
2+
lazy val f: scala.Function1[scala.Int, scala.Int] = ((x: scala.Int) => scala.Predef.identity[scala.Int](x))
3+
()
4+
}

tests/run-with-compiler/i5152.scala

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import scala.quoted._
2+
3+
object Test {
4+
implicit val toolbox: scala.quoted.Toolbox = scala.quoted.Toolbox.make
5+
6+
def eval1(ff: Expr[Int => Int]): Expr[Int => Int] = '(identity)
7+
8+
def peval1(): Expr[Unit] = '{
9+
lazy val f: Int => Int = ~eval1('((y: Int) => f(y)))
10+
}
11+
12+
def main(args: Array[String]): Unit = {
13+
val p = peval1()
14+
println(p.show)
15+
}
16+
17+
}

0 commit comments

Comments
 (0)