Skip to content

Commit 297e9fc

Browse files
Merge pull request #4538 from dotty-staging/quote-pickle-expr-only
Pickle quotes directly as expressions in TASTY
2 parents df00a67 + 40b200a commit 297e9fc

File tree

8 files changed

+90
-31
lines changed

8 files changed

+90
-31
lines changed

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

Lines changed: 4 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,7 @@ object PickledQuotes {
4646
if (ctx.reporter.hasErrors) Nil
4747
else {
4848
assert(!tree.isInstanceOf[Hole]) // Should not be pickled as it represents `'(~x)` which should be optimized to `x`
49-
val encapsulated = encapsulateQuote(tree)
50-
val pickled = pickle(encapsulated)
49+
val pickled = pickle(tree)
5150
TastyString.pickle(pickled)
5251
}
5352
}
@@ -75,37 +74,13 @@ object PickledQuotes {
7574
/** Unpickle the tree contained in the TastyExpr */
7675
private def unpickleExpr(expr: TastyExpr[_])(implicit ctx: Context): Tree = {
7776
val tastyBytes = TastyString.unpickle(expr.tasty)
78-
val unpickled = unpickle(tastyBytes, expr.args)
79-
unpickled match {
80-
case PackageDef(_, (vdef: ValDef) :: Nil) =>
81-
vdef.rhs.changeOwner(vdef.symbol, ctx.owner)
82-
}
77+
unpickle(tastyBytes, expr.args)
8378
}
8479

8580
/** Unpickle the tree contained in the TastyType */
8681
private def unpickleType(ttpe: TastyType[_])(implicit ctx: Context): Tree = {
8782
val tastyBytes = TastyString.unpickle(ttpe.tasty)
88-
val unpickled = unpickle(tastyBytes, ttpe.args)
89-
unpickled match {
90-
case PackageDef(_, (vdef: ValDef) :: Nil) =>
91-
vdef.rhs.asInstanceOf[TypeApply].args.head
92-
.changeOwner(vdef.symbol, ctx.owner)
93-
}
94-
}
95-
96-
/** Encapsulate the tree in a top level `val` or `type`
97-
* `<tree>` ==> `package _root_ { val $quote: Any = <tree> }`
98-
* or
99-
* `<type tree>` ==> `package _root_ { val $typeQuote: Any = null.asInstanceOf[<tree>] }`
100-
*/
101-
private def encapsulateQuote(tree: Tree)(implicit ctx: Context): Tree = {
102-
val name = (if (tree.isTerm) "$quote" else "$typeQuote").toTermName
103-
val sym = ctx.newSymbol(ctx.owner, name, Synthetic, defn.AnyType, coord = tree.pos)
104-
val encoded =
105-
if (tree.isTerm) tree
106-
else Literal(Constant(null)).select(nme.asInstanceOf_).appliedToTypeTrees(tree :: Nil)
107-
val quoted = ValDef(sym, encoded).withPos(tree.pos)
108-
PackageDef(ref(defn.RootPackage).asInstanceOf[Ident], quoted :: Nil).withPos(tree.pos)
83+
unpickle(tastyBytes, ttpe.args)
10984
}
11085

11186
// TASTY picklingtests/pos/quoteTest.scala
@@ -135,8 +110,7 @@ object PickledQuotes {
135110
/** Unpickle TASTY bytes into it's tree */
136111
private def unpickle(bytes: Array[Byte], splices: Seq[Any])(implicit ctx: Context): Tree = {
137112
val unpickler = new TastyUnpickler(bytes, splices)
138-
unpickler.enter(roots = Set(defn.RootPackage))
139-
val tree = unpickler.tree
113+
val tree = unpickler.unpickleExpr()
140114
if (pickling ne noPrinter) {
141115
println(i"**** unpickled quote for \n${tree.show}")
142116
new TastyPrinter(bytes).printContents()

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -46,6 +46,9 @@ class DottyUnpickler(bytes: Array[Byte]) extends ClassfileParser.Embedded with t
4646
def enter(roots: Set[SymDenotation])(implicit ctx: Context): Unit =
4747
treeUnpickler.enterTopLevel(roots)
4848

49+
def unpickleExpr()(implicit ctx: Context): Tree =
50+
treeUnpickler.unpickleExpr()
51+
4952
protected def treeSectionUnpickler(posUnpicklerOpt: Option[PositionUnpickler]): TreeSectionUnpickler = {
5053
new TreeSectionUnpickler(posUnpicklerOpt)
5154
}

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

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,11 +73,18 @@ class TreeUnpickler(reader: TastyReader,
7373
*/
7474
def enterTopLevel(roots: Set[SymDenotation])(implicit ctx: Context): Unit = {
7575
this.roots = roots
76-
var rdr = new TreeReader(reader).fork
76+
val rdr = new TreeReader(reader).fork
7777
ownerTree = new OwnerTree(NoAddr, 0, rdr.fork, reader.endAddr)
7878
rdr.indexStats(reader.endAddr)
7979
}
8080

81+
def unpickleExpr()(implicit ctx: Context): Tree = {
82+
this.roots = Set(ctx.owner)
83+
val rdr = new TreeReader(reader).fork
84+
ownerTree = new OwnerTree(NoAddr, 0, rdr.fork, reader.endAddr)
85+
rdr.readTerm()
86+
}
87+
8188
/** The unpickled trees */
8289
def unpickle()(implicit ctx: Context): List[Tree] = {
8390
assert(roots != null, "unpickle without previous enterTopLevel")
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
3
2+
{
3+
def ff: Int =
4+
{
5+
val a: List[Int] =
6+
{
7+
type T = List[Int]
8+
val b: T = Nil.::[Int](3)
9+
b: List[Int]
10+
}
11+
a.head: Int
12+
}
13+
ff: Int
14+
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
2+
import quoted._
3+
import dotty.tools.dotc.quoted.Toolbox._
4+
5+
object Test {
6+
def main(args: Array[String]): Unit = {
7+
val q = f(g(Type.IntTag))
8+
println(q.run)
9+
println(q.show)
10+
}
11+
12+
def f(t: Type[List[Int]]): Expr[Int] = '{
13+
def ff: Int = {
14+
val a: ~t = {
15+
type T = ~t
16+
val b: T = 3 :: Nil
17+
b
18+
}
19+
a.head
20+
}
21+
ff
22+
}
23+
24+
def g[T](a: Type[T]): Type[List[T]] = '[List[~a]]
25+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
9
2+
{
3+
def ff: Int =
4+
{
5+
val a: Int = 9
6+
a.+(0)
7+
}
8+
ff: Int
9+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import quoted._
2+
import dotty.tools.dotc.quoted.Toolbox._
3+
4+
object Test {
5+
def main(args: Array[String]): Unit = {
6+
val q = f
7+
println(q.run)
8+
println(q.show)
9+
}
10+
11+
def f: Expr[Int] = '{
12+
def ff: Int = {
13+
~g
14+
}
15+
ff
16+
}
17+
18+
def g: Expr[Int] = '{
19+
val a = 9
20+
a + 0
21+
}
22+
}

tests/run-with-compiler/quote-run-large.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,11 @@ object Test {
5151
def foo42: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
5252
def foo43: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
5353
def foo44: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
54+
def foo45: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
55+
def foo46: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
56+
def foo47: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
57+
def foo48: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
58+
def foo49: Int = x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x + x
5459
}
5560

5661
new Foo(5)

0 commit comments

Comments
 (0)