Skip to content

Commit 7c7f687

Browse files
Merge pull request #5344 from dotty-staging/fix-quote-owner
Fix owner of Expr/Type represented with trees
2 parents 714ce80 + 8774dbe commit 7c7f687

File tree

5 files changed

+41
-2
lines changed

5 files changed

+41
-2
lines changed

compiler/src/dotty/tools/dotc/core/quoted/PickledQuotes.scala

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,7 @@ object PickledQuotes {
4646
case value: Class[_] => ref(defn.Predef_classOf).appliedToType(classToType(value))
4747
case value => Literal(Constant(value))
4848
}
49-
case expr: TastyTreeExpr[Tree] @unchecked => expr.tree
49+
case expr: TastyTreeExpr[Tree] @unchecked => healOwner(expr.tree)
5050
case expr: FunctionAppliedTo[_, _] =>
5151
functionAppliedTo(quotedExprToTree(expr.f), quotedExprToTree(expr.x))
5252
}
@@ -55,7 +55,7 @@ object PickledQuotes {
5555
def quotedTypeToTree(expr: quoted.Type[_])(implicit ctx: Context): Tree = expr match {
5656
case expr: TastyType[_] => unpickleType(expr)
5757
case expr: TaggedType[_] => classTagToTypeTree(expr.ct)
58-
case expr: TreeType[Tree] @unchecked => expr.typeTree
58+
case expr: TreeType[Tree] @unchecked => healOwner(expr.typeTree)
5959
}
6060

6161
/** Unpickle the tree contained in the TastyExpr */
@@ -170,4 +170,21 @@ object PickledQuotes {
170170
}
171171
} else ctx.getClassIfDefined(clazz.getCanonicalName).typeRef
172172
}
173+
174+
/** Make sure that the owner of this tree is `ctx.owner` */
175+
private def healOwner(tree: Tree)(implicit ctx: Context): Tree = {
176+
val getCurrentOwner = new TreeAccumulator[Option[Symbol]] {
177+
def apply(x: Option[Symbol], tree: tpd.Tree)(implicit ctx: Context): Option[Symbol] = {
178+
if (x.isDefined) x
179+
else tree match {
180+
case tree: DefTree => Some(tree.symbol.owner)
181+
case _ => foldOver(x, tree)
182+
}
183+
}
184+
}
185+
getCurrentOwner(None, tree) match {
186+
case Some(owner) if owner != ctx.owner => tree.changeOwner(owner, ctx.owner)
187+
case _ => tree
188+
}
189+
}
173190
}

compiler/test/dotc/run-test-pickling.blacklist

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ mixins1
3838
outerPatternMatch
3939
paramForwarding_separate
4040
quote-and-splice
41+
quote-change-owner
4142
quote-force
4243
quote-indexed-map-by-name
4344
quote-sep-comp

tests/run/quote-change-owner.check

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
bar
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
import scala.quoted._
2+
object Macros {
3+
inline def assert2(expr: => Boolean): Unit = ~ assertImpl('(expr))
4+
def assertImpl(expr: Expr[Boolean]) = '{
5+
def foo(): Unit = ~expr
6+
foo()
7+
}
8+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
import Macros._
2+
object Test {
3+
def main(args: Array[String]): Unit = {
4+
assert2 {
5+
def bar(): Boolean = {
6+
println("bar")
7+
false
8+
}
9+
bar()
10+
}
11+
}
12+
}

0 commit comments

Comments
 (0)