aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-02-26 14:26:15 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-03-18 11:14:11 +0100
commit21f042ecaf136ce544ec899f42e70e2e1a1addf8 (patch)
tree06b2c1a65832abf5ef4e5a6773fd4e44df56eaa2 /src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala
parent76bf36dd64c05fbbf6fd804983379c8c31f52c9d (diff)
downloaddotty-21f042ecaf136ce544ec899f42e70e2e1a1addf8.tar.gz
dotty-21f042ecaf136ce544ec899f42e70e2e1a1addf8.tar.bz2
dotty-21f042ecaf136ce544ec899f42e70e2e1a1addf8.zip
Avoid capturing context in lazy trees
Lazy trees can live longer than runs, so it is important that they capture as little as possible. In particular they should not capture contexts. This change led with a ripple through effect to many changes where operations now have to parameterzied with contexts, in particular in what concerns tree folding. The changes in turn uncovered some areas where dotc was incompatible with scalac, and flagged correct things as errors. These will be fixed in the next commits. Another small twist: EmptyTrees will not be read in delayed mode, so that one can check for lacking definitions without deserializing the rhs.
Diffstat (limited to 'src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala')
-rw-r--r--src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala16
1 files changed, 9 insertions, 7 deletions
diff --git a/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala b/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala
index c6c099f2e..72020012d 100644
--- a/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala
+++ b/src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala
@@ -365,7 +365,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, readPositio
readByte()
val end = readEnd()
val sym = readType().typeSymbol
- val lazyAnnotTree = readLater(end, _.readTerm())
+ val lazyAnnotTree = readLater(end, rdr => ctx => rdr.readTerm()(ctx))
annots += Annotation.deferred(sym, _ => lazyAnnotTree.complete)
case _ =>
assert(false, s"illegal modifier tag at $currentAddr")
@@ -424,7 +424,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, readPositio
}
}
- def readRhs(implicit ctx: Context) = readLater(end, _.readTerm())
+ def readRhs(implicit ctx: Context) =
+ if (nextByte == EMPTYTREE) EmptyTree
+ else readLater(end, rdr => ctx => rdr.readTerm()(ctx))
def localCtx = ctx.fresh.setOwner(sym)
@@ -499,7 +501,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, readPositio
else EmptyValDef
fork.indexStats(end)
val constr = readIndexedDef().asInstanceOf[DefDef]
- val lazyStats = readLater(end, _.readIndexedStats(localDummy, end))
+ val lazyStats = readLater(end, rdr => ctx => rdr.readIndexedStats(localDummy, end)(ctx))
addAddr(start,
untpd.Template(constr, parents, self, lazyStats)
.withType(localDummy.nonMemberTermRef))
@@ -659,7 +661,7 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, readPositio
}
}
- def readLater[T](end: Addr, op: TreeReader => T)(implicit ctx: Context): Trees.Lazy[T] = {
+ def readLater[T <: AnyRef](end: Addr, op: TreeReader => Context => T): Trees.Lazy[T] = {
val localReader = fork
skipTo(end)
new LazyReader(localReader, op)
@@ -704,9 +706,9 @@ class TreeUnpickler(reader: TastyReader, tastyName: TastyName.Table, readPositio
}
}
- class LazyReader[T](reader: TreeReader, op: TreeReader => T)(implicit ctx: Context) extends Trees.Lazy[T] with DeferredPosition {
- def complete: T = {
- val res = op(reader)
+ class LazyReader[T <: AnyRef](reader: TreeReader, op: TreeReader => Context => T) extends Trees.Lazy[T] with DeferredPosition {
+ def complete(implicit ctx: Context): T = {
+ val res = op(reader)(ctx)
normalizePos(res, parentPos)
res
}