diff options
author | Martin Odersky <odersky@gmail.com> | 2015-02-26 14:26:15 +0100 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-03-18 11:14:11 +0100 |
commit | 21f042ecaf136ce544ec899f42e70e2e1a1addf8 (patch) | |
tree | 06b2c1a65832abf5ef4e5a6773fd4e44df56eaa2 /src/dotty/tools/dotc/ast/TreeInfo.scala | |
parent | 76bf36dd64c05fbbf6fd804983379c8c31f52c9d (diff) | |
download | dotty-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/ast/TreeInfo.scala')
-rw-r--r-- | src/dotty/tools/dotc/ast/TreeInfo.scala | 16 |
1 files changed, 9 insertions, 7 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 { |