aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
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
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')
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala16
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala70
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala30
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala8
-rw-r--r--src/dotty/tools/dotc/core/pickling/TreeUnpickler.scala16
-rw-r--r--src/dotty/tools/dotc/transform/CapturedVars.scala2
-rw-r--r--src/dotty/tools/dotc/transform/Constructors.scala2
-rw-r--r--src/dotty/tools/dotc/transform/LambdaLift.scala4
-rw-r--r--src/dotty/tools/dotc/transform/Pickler.scala2
-rw-r--r--src/dotty/tools/dotc/typer/Checking.scala2
-rw-r--r--src/dotty/tools/dotc/typer/VarianceChecker.scala2
11 files changed, 81 insertions, 73 deletions
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 6ebf29ffa..5338297e8 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -28,7 +28,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
*/
def isPureInterfaceMember(tree: Tree): Boolean = unsplice(tree) match {
case EmptyTree | Import(_, _) | TypeDef(_, _) => true
- case defn: ValOrDefDef => defn.rhs.isEmpty
+ case defn: ValOrDefDef => defn.unforcedRhs == EmptyTree
case _ => false
}
@@ -89,7 +89,7 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
}
/** If tree is a closure, it's body, otherwise tree itself */
- def closureBody(tree: tpd.Tree): tpd.Tree = tree match {
+ def closureBody(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = tree match {
case Block((meth @ DefDef(nme.ANON_FUN, _, _, _, _)) :: Nil, Closure(_, _, _)) => meth.rhs
case _ => tree
}
@@ -243,12 +243,14 @@ trait TreeInfo[T >: Untyped <: Type] { self: Trees.Instance[T] =>
/** Is this case guarded? */
def isGuardedCase(cdef: CaseDef) = cdef.guard ne EmptyTree
- /** True iff definition if a val or def with no right-hand-side, or it
+ /** True iff definition is a val or def with no right-hand-side, or it
* is an abstract typoe declaration
*/
def lacksDefinition(mdef: MemberDef)(implicit ctx: Context) = mdef match {
- case mdef: ValOrDefDef => mdef.rhs.isEmpty && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor)
- case mdef: TypeDef => mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree]
+ case mdef: ValOrDefDef =>
+ mdef.unforcedRhs == EmptyTree && !mdef.name.isConstructorName && !mdef.mods.is(ParamAccessor)
+ case mdef: TypeDef =>
+ mdef.rhs.isEmpty || mdef.rhs.isInstanceOf[TypeBoundsTree]
case _ => false
}
@@ -409,7 +411,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
/** The variables defined by a pattern, in reverse order of their appearance. */
def patVars(tree: Tree)(implicit ctx: Context): List[Symbol] = {
val acc = new TreeAccumulator[List[Symbol]] {
- def apply(syms: List[Symbol], tree: Tree) = tree match {
+ def apply(syms: List[Symbol], tree: Tree)(implicit ctx: Context) = tree match {
case Bind(_, body) => apply(tree.symbol :: syms, body)
case _ => foldOver(syms, tree)
}
@@ -451,7 +453,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
def defPath(sym: Symbol, root: Tree)(implicit ctx: Context): List[Tree] = ctx.debugTraceIndented(s"defpath($sym with position ${sym.pos}, ${root.show})") {
require(sym.pos.exists)
object accum extends TreeAccumulator[List[Tree]] {
- def apply(x: List[Tree], tree: Tree): List[Tree] = {
+ def apply(x: List[Tree], tree: Tree)(implicit ctx: Context): List[Tree] = {
if (tree.envelope.contains(sym.pos))
if (definedSym(tree) == sym) tree :: x
else {
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index b0dc8a089..78291c843 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -76,6 +76,9 @@ object Trees {
}
private var nextId = 0 // for debugging
+
+ type LazyTree = AnyRef /* really: Tree | Lazy[Tree] */
+ type LazyTreeList = AnyRef /* really: List[Tree] | Lazy[List[Tree]] */
/** Trees take a parameter indicating what the type of their `tpe` field
* is. Two choices: `Type` or `Untyped`.
@@ -336,7 +339,8 @@ object Trees {
/** A ValDef or DefDef tree */
trait ValOrDefDef[-T >: Untyped] extends MemberDef[T] with WithLazyField[Tree[T]] {
def tpt: Tree[T]
- def rhs: Tree[T] = forceIfLazy
+ def unforcedRhs: LazyTree = unforced
+ def rhs(implicit ctx: Context): Tree[T] = forceIfLazy
}
// ----------- Tree case classes ------------------------------------
@@ -619,23 +623,22 @@ object Trees {
}
/** mods val name: tpt = rhs */
- case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], private var preRhs: Any /*Tree[T] | Lazy[Tree[T]]*/)
+ case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], private var preRhs: LazyTree)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = ValDef[T]
assert(isEmpty || tpt != genericEmptyTree)
def unforced = preRhs
- protected def force(x: Any) = preRhs = x
+ protected def force(x: AnyRef) = preRhs = x
}
/** mods def name[tparams](vparams_1)...(vparams_n): tpt = rhs */
case class DefDef[-T >: Untyped] private[ast] (name: TermName, tparams: List[TypeDef[T]],
- vparamss: List[List[ValDef[T]]], tpt: Tree[T], private var preRhs: Any /*Tree[T] | Lazy[Tree[T]]*/)
+ vparamss: List[List[ValDef[T]]], tpt: Tree[T], private var preRhs: LazyTree)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = DefDef[T]
assert(tpt != genericEmptyTree)
- def unforcedRhs = preRhs
def unforced = preRhs
- protected def force(x: Any) = preRhs = x
+ protected def force(x: AnyRef) = preRhs = x
}
/** mods class name template or
@@ -658,12 +661,13 @@ object Trees {
}
/** extends parents { self => body } */
- case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], private var preBody: Any /*List[Tree[T]] | Lazy[List[Tree]]]*/)
+ case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], private var preBody: LazyTreeList)
extends DefTree[T] with WithLazyField[List[Tree[T]]] {
type ThisTree[-T >: Untyped] = Template[T]
+ def unforcedBody = unforced
def unforced = preBody
- protected def force(x: Any) = preBody = x
- def body: List[Tree[T]] = forceIfLazy
+ protected def force(x: AnyRef) = preBody = x
+ def body(implicit ctx: Context): List[Tree[T]] = forceIfLazy
}
/** import expr.selectors
@@ -762,10 +766,10 @@ object Trees {
* proxied `unforced` and `force`. Forcing the field will
* set the `var` to the underlying value.
*/
- trait WithLazyField[+T] {
- def unforced: Any
- protected def force(x: Any): Unit
- def forceIfLazy: T = unforced match {
+ trait WithLazyField[+T <: AnyRef] {
+ def unforced: AnyRef
+ protected def force(x: AnyRef): Unit
+ def forceIfLazy(implicit ctx: Context): T = unforced match {
case lzy: Lazy[T] =>
val x = lzy.complete
force(x)
@@ -778,8 +782,8 @@ object Trees {
* These can be instantiated with Lazy instances which
* can delay tree construction until the field is first demanded.
*/
- trait Lazy[T] {
- def complete: T
+ trait Lazy[T <: AnyRef] {
+ def complete(implicit ctx: Context): T
}
// ----- Generic Tree Instances, inherited from `tpt` and `untpd`.
@@ -1026,20 +1030,20 @@ object Trees {
case tree: UnApply if (fun eq tree.fun) && (implicits eq tree.implicits) && (patterns eq tree.patterns) => tree
case _ => finalize(tree, untpd.UnApply(fun, implicits, patterns))
}
- def ValDef(tree: Tree)(name: TermName, tpt: Tree, rhs: Tree): ValDef = tree match {
- case tree: ValDef if (name == tree.name) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
+ def ValDef(tree: Tree)(name: TermName, tpt: Tree, rhs: LazyTree): ValDef = tree match {
+ case tree: ValDef if (name == tree.name) && (tpt eq tree.tpt) && (rhs eq tree.unforcedRhs) => tree
case _ => finalize(tree, untpd.ValDef(name, tpt, rhs))
}
- def DefDef(tree: Tree)(name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = tree match {
- case tree: DefDef if (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.rhs) => tree
+ def DefDef(tree: Tree)(name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: LazyTree): DefDef = tree match {
+ case tree: DefDef if (name == tree.name) && (tparams eq tree.tparams) && (vparamss eq tree.vparamss) && (tpt eq tree.tpt) && (rhs eq tree.unforcedRhs) => tree
case _ => finalize(tree, untpd.DefDef(name, tparams, vparamss, tpt, rhs))
}
def TypeDef(tree: Tree)(name: TypeName, rhs: Tree, tparams: List[untpd.TypeDef]): TypeDef = tree match {
case tree: TypeDef if (name == tree.name) && (rhs eq tree.rhs) && (tparams eq tree.tparams) => tree
case _ => finalize(tree, untpd.TypeDef(name, tparams, rhs))
}
- def Template(tree: Tree)(constr: DefDef, parents: List[Tree], self: ValDef, body: List[Tree]): Template = tree match {
- case tree: Template if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.body) => tree
+ def Template(tree: Tree)(constr: DefDef, parents: List[Tree], self: ValDef, body: LazyTreeList): Template = tree match {
+ case tree: Template if (constr eq tree.constr) && (parents eq tree.parents) && (self eq tree.self) && (body eq tree.unforcedBody) => tree
case _ => finalize(tree, untpd.Template(constr, parents, self, body))
}
def Import(tree: Tree)(expr: Tree, selectors: List[untpd.Tree]): Import = tree match {
@@ -1071,13 +1075,13 @@ object Trees {
Try(tree: Tree)(expr, cases, finalizer)
def UnApply(tree: UnApply)(fun: Tree = tree.fun, implicits: List[Tree] = tree.implicits, patterns: List[Tree] = tree.patterns): UnApply =
UnApply(tree: Tree)(fun, implicits, patterns)
- def ValDef(tree: ValDef)(name: TermName = tree.name, tpt: Tree = tree.tpt, rhs: Tree = tree.rhs): ValDef =
+ def ValDef(tree: ValDef)(name: TermName = tree.name, tpt: Tree = tree.tpt, rhs: LazyTree = tree.unforcedRhs): ValDef =
ValDef(tree: Tree)(name, tpt, rhs)
- def DefDef(tree: DefDef)(name: TermName = tree.name, tparams: List[TypeDef] = tree.tparams, vparamss: List[List[ValDef]] = tree.vparamss, tpt: Tree = tree.tpt, rhs: Tree = tree.rhs): DefDef =
+ def DefDef(tree: DefDef)(name: TermName = tree.name, tparams: List[TypeDef] = tree.tparams, vparamss: List[List[ValDef]] = tree.vparamss, tpt: Tree = tree.tpt, rhs: LazyTree = tree.unforcedRhs): DefDef =
DefDef(tree: Tree)(name, tparams, vparamss, tpt, rhs)
def TypeDef(tree: TypeDef)(name: TypeName = tree.name, rhs: Tree = tree.rhs, tparams: List[untpd.TypeDef] = tree.tparams): TypeDef =
TypeDef(tree: Tree)(name, rhs, tparams)
- def Template(tree: Template)(constr: DefDef = tree.constr, parents: List[Tree] = tree.parents, self: ValDef = tree.self, body: List[Tree] = tree.body): Template =
+ def Template(tree: Template)(constr: DefDef = tree.constr, parents: List[Tree] = tree.parents, self: ValDef = tree.self, body: LazyTreeList = tree.unforcedBody): Template =
Template(tree: Tree)(constr, parents, self, body)
}
@@ -1181,10 +1185,10 @@ object Trees {
transform(trees).asInstanceOf[List[Tr]]
}
- abstract class TreeAccumulator[X] extends ((X, Tree) => X) {
- def apply(x: X, tree: Tree): X
- def apply(x: X, trees: Traversable[Tree]): X = (x /: trees)(apply)
- def foldOver(x: X, tree: Tree): X = tree match {
+ abstract class TreeAccumulator[X] {
+ def apply(x: X, tree: Tree)(implicit ctx: Context): X
+ def apply(x: X, trees: Traversable[Tree])(implicit ctx: Context): X = (x /: trees)(apply)
+ def foldOver(x: X, tree: Tree)(implicit ctx: Context): X = tree match {
case Ident(name) =>
x
case Select(qualifier, name) =>
@@ -1269,21 +1273,21 @@ object Trees {
}
abstract class TreeTraverser extends TreeAccumulator[Unit] {
- def traverse(tree: Tree): Unit
- def apply(x: Unit, tree: Tree) = traverse(tree)
- protected def traverseChildren(tree: Tree) = foldOver((), tree)
+ def traverse(tree: Tree)(implicit ctx: Context): Unit
+ def apply(x: Unit, tree: Tree)(implicit ctx: Context) = traverse(tree)
+ protected def traverseChildren(tree: Tree)(implicit ctx: Context) = foldOver((), tree)
}
/** Fold `f` over all tree nodes, in depth-first, prefix order */
class DeepFolder[X](f: (X, Tree) => X) extends TreeAccumulator[X] {
- def apply(x: X, tree: Tree): X = foldOver(f(x, tree), tree)
+ def apply(x: X, tree: Tree)(implicit ctx: Context): X = foldOver(f(x, tree), tree)
}
/** Fold `f` over all tree nodes, in depth-first, prefix order, but don't visit
* subtrees where `f` returns a different result for the root, i.e. `f(x, root) ne x`.
*/
class ShallowFolder[X](f: (X, Tree) => X) extends TreeAccumulator[X] {
- def apply(x: X, tree: Tree): X = {
+ def apply(x: X, tree: Tree)(implicit ctx: Context): X = {
val x1 = f(x, tree)
if (x1.asInstanceOf[AnyRef] ne x1.asInstanceOf[AnyRef]) x1
else foldOver(x1, tree)
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 49358a1c0..de8811115 100644
--- a/src/dotty/tools/dotc/ast/tpd.scala
+++ b/src/dotty/tools/dotc/ast/tpd.scala
@@ -161,7 +161,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def UnApply(fun: Tree, implicits: List[Tree], patterns: List[Tree], proto: Type)(implicit ctx: Context): UnApply =
ta.assignType(untpd.UnApply(fun, implicits, patterns), proto)
- def ValDef(sym: TermSymbol, rhs: Any /*Tree | Lazy[Tree]*/ = EmptyTree)(implicit ctx: Context): ValDef =
+ def ValDef(sym: TermSymbol, rhs: LazyTree = EmptyTree)(implicit ctx: Context): ValDef =
ta.assignType(untpd.ValDef(sym.name, TypeTree(sym.info), rhs), sym)
def SyntheticValDef(name: TermName, rhs: Tree)(implicit ctx: Context): ValDef =
@@ -234,7 +234,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
for (tparam <- cls.typeParams if !(bodyTypeParams contains tparam))
yield TypeDef(tparam)
val findLocalDummy = new FindLocalDummyAccumulator(cls)
- val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy)
+ val localDummy = ((NoSymbol: Symbol) /: body)(findLocalDummy.apply)
.orElse(ctx.newLocalDummy(cls))
val impl = untpd.Template(constr, parents, selfType, newTypeParams ++ body)
.withType(localDummy.nonMemberTermRef)
@@ -382,7 +382,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
else Literal(Constant(null)).select(defn.Any_asInstanceOf).appliedToType(tpe)
}
private class FindLocalDummyAccumulator(cls: ClassSymbol)(implicit ctx: Context) extends TreeAccumulator[Symbol] {
- def apply(sym: Symbol, tree: Tree) =
+ def apply(sym: Symbol, tree: Tree)(implicit ctx: Context) =
if (sym.exists) sym
else if (tree.isDef) {
val owner = tree.symbol.owner
@@ -538,13 +538,13 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
case _ => false
}
- def shallowFold[T](z: T)(op: (T, tpd.Tree) => T) =
+ def shallowFold[T](z: T)(op: (T, tpd.Tree) => T)(implicit ctx: Context) =
new ShallowFolder(op).apply(z, tree)
- def deepFold[T](z: T)(op: (T, tpd.Tree) => T) =
+ def deepFold[T](z: T)(op: (T, tpd.Tree) => T)(implicit ctx: Context) =
new DeepFolder(op).apply(z, tree)
- def find[T](pred: (tpd.Tree) => Boolean): Option[tpd.Tree] =
+ def find[T](pred: (tpd.Tree) => Boolean)(implicit ctx: Context): Option[tpd.Tree] =
shallowFold[Option[tpd.Tree]](None)((accum, tree) => if (pred(tree)) Some(tree) else accum)
def subst(from: List[Symbol], to: List[Symbol])(implicit ctx: Context): ThisTree =
@@ -571,7 +571,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
def changeOwnerAfter(from: Symbol, to: Symbol, trans: DenotTransformer)(implicit ctx: Context): ThisTree = {
assert(ctx.phase == trans.next)
val traverser = new TreeTraverser {
- def traverse(tree: Tree) = tree match {
+ def traverse(tree: Tree)(implicit ctx: Context) = tree match {
case tree: DefTree =>
val sym = tree.symbol
if (sym.denot(ctx.withPhase(trans)).owner == from)
@@ -657,21 +657,21 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
// --- Higher order traversal methods -------------------------------
- def foreachSubTree(f: Tree => Unit): Unit = { //TODO should go in tpd.
+ def foreachSubTree(f: Tree => Unit)(implicit ctx: Context): Unit = { //TODO should go in tpd.
val traverser = new TreeTraverser {
- def traverse(tree: Tree) = foldOver(f(tree), tree)
+ def traverse(tree: Tree)(implicit ctx: Context) = foldOver(f(tree), tree)
}
traverser.traverse(tree)
}
- def existsSubTree(p: Tree => Boolean): Boolean = {
+ def existsSubTree(p: Tree => Boolean)(implicit ctx: Context): Boolean = {
val acc = new TreeAccumulator[Boolean] {
- def apply(x: Boolean, t: Tree) = x || p(t) || foldOver(x, t)
+ def apply(x: Boolean, t: Tree)(implicit ctx: Context) = x || p(t) || foldOver(x, t)
}
acc(false, tree)
}
- def filterSubTrees(f: Tree => Boolean): List[Tree] = {
+ def filterSubTrees(f: Tree => Boolean)(implicit ctx: Context): List[Tree] = {
val buf = new mutable.ListBuffer[Tree]
foreachSubTree { tree => if (f(tree)) buf += tree }
buf.toList
@@ -770,9 +770,9 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
/** A traverser that passes the enlcosing class or method as an argumenr
* to the traverse method.
*/
- abstract class EnclosingMethodTraverser(implicit ctx: Context) extends TreeAccumulator[Symbol] {
- def traverse(enclMeth: Symbol, tree: Tree): Unit
- def apply(enclMeth: Symbol, tree: Tree) = {
+ abstract class EnclosingMethodTraverser extends TreeAccumulator[Symbol] {
+ def traverse(enclMeth: Symbol, tree: Tree)(implicit ctx: Context): Unit
+ def apply(enclMeth: Symbol, tree: Tree)(implicit ctx: Context) = {
tree match {
case _: DefTree if tree.symbol.exists =>
traverse(tree.symbol.enclosingMethod, tree)
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index d7791bfa5..1c1f7dd61 100644
--- a/src/dotty/tools/dotc/ast/untpd.scala
+++ b/src/dotty/tools/dotc/ast/untpd.scala
@@ -142,10 +142,10 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
def Bind(name: Name, body: Tree): Bind = new Bind(name, body)
def Alternative(trees: List[Tree]): Alternative = new Alternative(trees)
def UnApply(fun: Tree, implicits: List[Tree], patterns: List[Tree]): UnApply = new UnApply(fun, implicits, patterns)
- def ValDef(name: TermName, tpt: Tree, rhs: Any /*Tree | Lazy[Tree]*/): ValDef = new ValDef(name, tpt, rhs)
- def DefDef(name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Any /*Tree | Lazy[Tree]*/): DefDef = new DefDef(name, tparams, vparamss, tpt, rhs)
+ def ValDef(name: TermName, tpt: Tree, rhs: LazyTree): ValDef = new ValDef(name, tpt, rhs)
+ def DefDef(name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: LazyTree): DefDef = new DefDef(name, tparams, vparamss, tpt, rhs)
def TypeDef(name: TypeName, rhs: Tree): TypeDef = new TypeDef(name, rhs)
- def Template(constr: DefDef, parents: List[Tree], self: ValDef, body:Any /* List[Tree] | lazy[List[Tree]]*/): Template = new Template(constr, parents, self, body)
+ def Template(constr: DefDef, parents: List[Tree], self: ValDef, body: LazyTreeList): Template = new Template(constr, parents, self, body)
def Import(expr: Tree, selectors: List[untpd.Tree]): Import = new Import(expr, selectors)
def PackageDef(pid: RefTree, stats: List[Tree]): PackageDef = new PackageDef(pid, stats)
def Annotated(annot: Tree, arg: Tree): Annotated = new Annotated(annot, arg)
@@ -389,7 +389,7 @@ object untpd extends Trees.Instance[Untyped] with UntypedTreeInfo {
}
abstract class UntypedTreeAccumulator[X] extends TreeAccumulator[X] {
- override def foldOver(x: X, tree: Tree): X = tree match {
+ override def foldOver(x: X, tree: Tree)(implicit ctx: Context): X = tree match {
case ModuleDef(name, impl) =>
this(x, impl)
case SymbolLit(str) =>
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
}
diff --git a/src/dotty/tools/dotc/transform/CapturedVars.scala b/src/dotty/tools/dotc/transform/CapturedVars.scala
index 68bda9782..77b912f08 100644
--- a/src/dotty/tools/dotc/transform/CapturedVars.scala
+++ b/src/dotty/tools/dotc/transform/CapturedVars.scala
@@ -29,7 +29,7 @@ class CapturedVars extends MiniPhase with IdentityDenotTransformer { thisTransfo
private class CollectCaptured(implicit ctx: Context) extends EnclosingMethodTraverser {
private val captured = mutable.HashSet[Symbol]()
- def traverse(enclMeth: Symbol, tree: Tree) = tree match {
+ def traverse(enclMeth: Symbol, tree: Tree)(implicit ctx: Context) = tree match {
case id: Ident =>
val sym = id.symbol
if (sym.is(Mutable, butNot = Method) && sym.owner.isTerm && sym.enclosingMethod != enclMeth) {
diff --git a/src/dotty/tools/dotc/transform/Constructors.scala b/src/dotty/tools/dotc/transform/Constructors.scala
index f61ee68b9..165210cfb 100644
--- a/src/dotty/tools/dotc/transform/Constructors.scala
+++ b/src/dotty/tools/dotc/transform/Constructors.scala
@@ -114,7 +114,7 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor
private val seen = mutable.Set[Symbol](accessors: _*)
val retained = mutable.Set[Symbol]()
def dropped: collection.Set[Symbol] = seen -- retained
- override def traverse(tree: Tree) = {
+ override def traverse(tree: Tree)(implicit ctx: Context) = {
val sym = tree.symbol
tree match {
case Ident(_) | Select(This(_), _) if inConstr && seen(tree.symbol) =>
diff --git a/src/dotty/tools/dotc/transform/LambdaLift.scala b/src/dotty/tools/dotc/transform/LambdaLift.scala
index 1363615a5..a42e0cc35 100644
--- a/src/dotty/tools/dotc/transform/LambdaLift.scala
+++ b/src/dotty/tools/dotc/transform/LambdaLift.scala
@@ -161,8 +161,8 @@ class LambdaLift extends MiniPhase with IdentityDenotTransformer { thisTransform
if (callee.enclosingClass != caller.enclosingClass) calledFromInner += callee
}
- private class CollectDependencies(implicit ctx: Context) extends EnclosingMethodTraverser {
- def traverse(enclMeth: Symbol, tree: Tree) = try { //debug
+ private class CollectDependencies extends EnclosingMethodTraverser {
+ def traverse(enclMeth: Symbol, tree: Tree)(implicit ctx: Context) = try { //debug
val enclosure = enclMeth.skipConstructor
val sym = tree.symbol
def narrowTo(thisClass: ClassSymbol) = {
diff --git a/src/dotty/tools/dotc/transform/Pickler.scala b/src/dotty/tools/dotc/transform/Pickler.scala
index 7a13e1ed6..91d0fac34 100644
--- a/src/dotty/tools/dotc/transform/Pickler.scala
+++ b/src/dotty/tools/dotc/transform/Pickler.scala
@@ -31,7 +31,7 @@ class Pickler extends MiniPhaseTransform { thisTransform =>
// println(i"rawBytes = \n$rawBytes%\n%") // DEBUG
if (Printers.pickling ne Printers.noPrinter) new TastyPrinter(bytes).printContents()
- println(i"unpickled:\n ${new DottyUnpickler(bytes, readPositions = false).result}%\n%")
+ //println(i"unpickled:\n ${new DottyUnpickler(bytes, readPositions = false).result}%\n%")
}
tree
diff --git a/src/dotty/tools/dotc/typer/Checking.scala b/src/dotty/tools/dotc/typer/Checking.scala
index 1354b8926..f7502d56d 100644
--- a/src/dotty/tools/dotc/typer/Checking.scala
+++ b/src/dotty/tools/dotc/typer/Checking.scala
@@ -169,7 +169,7 @@ object Checking {
val checkTree = new TreeAccumulator[Unit] {
def checkRef(tree: Tree, sym: Symbol) =
if (sym.maybeOwner == refineCls && !seen(sym)) forwardRef(tree)
- def apply(x: Unit, tree: Tree) = tree match {
+ def apply(x: Unit, tree: Tree)(implicit ctx: Context) = tree match {
case tree: MemberDef =>
foldOver(x, tree)
seen += tree.symbol
diff --git a/src/dotty/tools/dotc/typer/VarianceChecker.scala b/src/dotty/tools/dotc/typer/VarianceChecker.scala
index 8fff52170..1d3ceaa57 100644
--- a/src/dotty/tools/dotc/typer/VarianceChecker.scala
+++ b/src/dotty/tools/dotc/typer/VarianceChecker.scala
@@ -116,7 +116,7 @@ class VarianceChecker()(implicit ctx: Context) {
case None =>
}
- override def traverse(tree: Tree) = {
+ override def traverse(tree: Tree)(implicit ctx: Context) = {
def sym = tree.symbol
// No variance check for private/protected[this] methods/values.
def skip = !sym.exists || sym.is(Local)