Skip to content

Commit 0e5d922

Browse files
Handle pickled forward references in pickled expressions (#16855)
To compute forward references it was assumed that the owner of that symbol can be found in the TASTy. This is not always the case with TASTy expressions of pickled quotes. The owner might be outside the quote, in this case the context already has the owner of the referenced symbol. These are local symbols defined at the top-level of the TASTy. Fixes #16843
2 parents 2602b55 + 96bfb69 commit 0e5d922

File tree

5 files changed

+38
-1
lines changed

5 files changed

+38
-1
lines changed

compiler/src/dotty/tools/dotc/core/tasty/TreeUnpickler.scala

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ class TreeUnpickler(reader: TastyReader,
7474
*/
7575
private val typeAtAddr = new mutable.HashMap[Addr, Type]
7676

77+
/** If this is a pickled quote, the owner of the quote, otherwise NoSymbol. */
78+
private var rootOwner: Symbol = NoSymbol
79+
7780
/** The root symbol denotation which are defined by the Tasty file associated with this
7881
* TreeUnpickler. Set by `enterTopLevel`.
7982
*/
@@ -106,6 +109,7 @@ class TreeUnpickler(reader: TastyReader,
106109

107110
/** The unpickled trees */
108111
def unpickle(mode: UnpickleMode)(using Context): List[Tree] = {
112+
if mode != UnpickleMode.TopLevel then rootOwner = ctx.owner
109113
assert(roots != null, "unpickle without previous enterTopLevel")
110114
val rdr = new TreeReader(reader)
111115
mode match {
@@ -1635,7 +1639,7 @@ class TreeUnpickler(reader: TastyReader,
16351639
pickling.println(i"no owner for $addr among $cs%, %")
16361640
throw ex
16371641
}
1638-
try search(children, NoSymbol)
1642+
try search(children, rootOwner)
16391643
catch {
16401644
case ex: TreeWithoutOwner =>
16411645
pickling.println(s"ownerTree = $ownerTree")
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import scala.quoted.*
2+
3+
case class Foo(x: Int)
4+
5+
inline def foo = ${ fooImpl }
6+
7+
def fooImpl(using Quotes) =
8+
val tmp = '{
9+
1 match
10+
case x @ (y: Int) => 0
11+
}
12+
13+
'{}

tests/pos-macros/i16843a/Test_2.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
val x = foo
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import scala.quoted.*
2+
3+
inline def foo: Int = ${ fooImpl }
4+
5+
def fooImpl(using Quotes): Expr[Int] =
6+
'{
7+
val b = ${
8+
val a = '{
9+
(1: Int) match
10+
case x @ (y: Int) => 0
11+
}
12+
a
13+
}
14+
15+
(1: Int) match
16+
case x @ (y: Int) => 0
17+
}
18+

tests/pos-macros/i16843b/Test_2.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
def test = foo

0 commit comments

Comments
 (0)