aboutsummaryrefslogtreecommitdiff
path: root/src/dotty/tools/dotc
diff options
context:
space:
mode:
authorMartin Odersky <odersky@gmail.com>2015-02-14 18:39:14 +0100
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-03-18 11:14:08 +0100
commit5b63106448275d6cc4bb6822af33247c2521a63c (patch)
tree4313312569f2ae3f15f8cb1c763bc30c19c1eeea /src/dotty/tools/dotc
parent9262d475e648219eb9ef4410d91621cc5f1f17cc (diff)
downloaddotty-5b63106448275d6cc4bb6822af33247c2521a63c.tar.gz
dotty-5b63106448275d6cc4bb6822af33247c2521a63c.tar.bz2
dotty-5b63106448275d6cc4bb6822af33247c2521a63c.zip
Make some tree fields lazy
Lazy fields are - the rhs field of a ValDef or DefDef - the body field of a Template These can be instantiated with Lazy instances. The scheme is such that lazy fields are completely transparent for users of the Trees API. The only downside is that the parameter used to initialize a potentially lazy field has a weak type (now it's Any, with Dotty it would be a union type of the form `T | Lazy[T]`. Therefore, the parameter cannot be recovered through pattern matching.
Diffstat (limited to 'src/dotty/tools/dotc')
-rw-r--r--src/dotty/tools/dotc/ast/Desugar.scala8
-rw-r--r--src/dotty/tools/dotc/ast/TreeInfo.scala11
-rw-r--r--src/dotty/tools/dotc/ast/TreeTypeMap.scala8
-rw-r--r--src/dotty/tools/dotc/ast/Trees.scala73
-rw-r--r--src/dotty/tools/dotc/ast/tpd.scala2
-rw-r--r--src/dotty/tools/dotc/ast/untpd.scala6
-rw-r--r--src/dotty/tools/dotc/printing/RefinedPrinter.scala14
-rw-r--r--src/dotty/tools/dotc/transform/Constructors.scala8
-rw-r--r--src/dotty/tools/dotc/transform/LazyVals.scala14
-rw-r--r--src/dotty/tools/dotc/transform/MacroTransform.scala4
-rw-r--r--src/dotty/tools/dotc/transform/RestoreScopes.scala4
-rw-r--r--src/dotty/tools/dotc/transform/SuperAccessors.scala4
-rw-r--r--src/dotty/tools/dotc/transform/TailRec.scala8
-rw-r--r--src/dotty/tools/dotc/typer/Namer.scala8
-rw-r--r--src/dotty/tools/dotc/typer/Typer.scala19
15 files changed, 113 insertions, 78 deletions
diff --git a/src/dotty/tools/dotc/ast/Desugar.scala b/src/dotty/tools/dotc/ast/Desugar.scala
index cd198818a..60ca45f28 100644
--- a/src/dotty/tools/dotc/ast/Desugar.scala
+++ b/src/dotty/tools/dotc/ast/Desugar.scala
@@ -218,7 +218,7 @@ object desugar {
/** The expansion of a class definition. See inline comments for what is involved */
def classDef(cdef: TypeDef)(implicit ctx: Context): Tree = {
- val TypeDef(name, impl @ Template(constr0, parents, self, body)) = cdef
+ val TypeDef(name, impl @ Template(constr0, parents, self, _)) = cdef
val mods = cdef.mods
val (constr1, defaultGetters) = defDef(constr0, isPrimaryConstructor = true) match {
@@ -242,7 +242,7 @@ object desugar {
val constr = cpy.DefDef(constr1)(tparams = constrTparams, vparamss = constrVparamss)
// Add constructor type parameters to auxiliary constructors
- val normalizedBody = body map {
+ val normalizedBody = impl.body map {
case ddef: DefDef if ddef.name.isConstructorName =>
cpy.DefDef(ddef)(tparams = constrTparams)
case stat =>
@@ -425,10 +425,10 @@ object desugar {
val modul = ValDef(name, clsRef, New(clsRef, Nil))
.withMods(mods | ModuleCreationFlags)
.withPos(mdef.pos)
- val ValDef(selfName, selfTpt, selfRhs) = tmpl.self
+ val ValDef(selfName, selfTpt, _) = tmpl.self
val selfMods = tmpl.self.mods
if (!selfTpt.isEmpty) ctx.error("object definition may not have a self type", tmpl.self.pos)
- val clsSelf = ValDef(selfName, SingletonTypeTree(Ident(name)), selfRhs)
+ val clsSelf = ValDef(selfName, SingletonTypeTree(Ident(name)), tmpl.self.rhs)
.withMods(selfMods)
.withPos(tmpl.self.pos orElse tmpl.pos.startPos)
val clsTmpl = cpy.Template(tmpl)(self = clsSelf, body = tmpl.body)
diff --git a/src/dotty/tools/dotc/ast/TreeInfo.scala b/src/dotty/tools/dotc/ast/TreeInfo.scala
index 3d633c58d..6ebf29ffa 100644
--- a/src/dotty/tools/dotc/ast/TreeInfo.scala
+++ b/src/dotty/tools/dotc/ast/TreeInfo.scala
@@ -28,8 +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 DefDef(_, _, _, _, rhs) => rhs.isEmpty
- case ValDef(_, _, rhs) => rhs.isEmpty
+ case defn: ValOrDefDef => defn.rhs.isEmpty
case _ => false
}
@@ -91,7 +90,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 {
- case Block(DefDef(nme.ANON_FUN, _, _, _, rhs) :: Nil, Closure(_, _, _)) => rhs
+ case Block((meth @ DefDef(nme.ANON_FUN, _, _, _, _)) :: Nil, Closure(_, _, _)) => meth.rhs
case _ => tree
}
@@ -287,8 +286,8 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
| Import(_, _)
| DefDef(_, _, _, _, _) =>
Pure
- case vdef @ ValDef(_, _, rhs) =>
- if (vdef.mods is Mutable) Impure else exprPurity(rhs)
+ case vdef @ ValDef(_, _, _) =>
+ if (vdef.mods is Mutable) Impure else exprPurity(vdef.rhs)
case _ =>
Impure
}
@@ -478,7 +477,7 @@ trait TypedTreeInfo extends TreeInfo[Type] { self: Trees.Instance[Type] =>
if (stats exists (definedSym(_) == sym)) stats else Nil
encl match {
case Block(stats, _) => verify(stats)
- case Template(_, _, _, stats) => verify(stats)
+ case encl: Template => verify(encl.body)
case PackageDef(_, stats) => verify(stats)
case _ => Nil
}
diff --git a/src/dotty/tools/dotc/ast/TreeTypeMap.scala b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
index 98027cd39..d2ec3ea10 100644
--- a/src/dotty/tools/dotc/ast/TreeTypeMap.scala
+++ b/src/dotty/tools/dotc/ast/TreeTypeMap.scala
@@ -78,22 +78,22 @@ final class TreeTypeMap(
}
override def transform(tree: tpd.Tree)(implicit ctx: Context): tpd.Tree = treeMap(tree) match {
- case impl @ Template(constr, parents, self, body) =>
+ case impl @ Template(constr, parents, self, _) =>
val tmap = withMappedSyms(localSyms(impl :: self :: Nil))
cpy.Template(impl)(
constr = tmap.transformSub(constr),
parents = parents mapconserve transform,
self = tmap.transformSub(self),
- body = body mapconserve tmap.transform
+ body = impl.body mapconserve tmap.transform
).withType(tmap.mapType(impl.tpe))
case tree1 =>
tree1.withType(mapType(tree1.tpe)) match {
case id: Ident if tpd.needsSelect(id.tpe) =>
ref(id.tpe.asInstanceOf[TermRef]).withPos(id.pos)
- case ddef @ DefDef(name, tparams, vparamss, tpt, rhs) =>
+ case ddef @ DefDef(name, tparams, vparamss, tpt, _) =>
val (tmap1, tparams1) = transformDefs(ddef.tparams)
val (tmap2, vparamss1) = tmap1.transformVParamss(vparamss)
- cpy.DefDef(ddef)(name, tparams1, vparamss1, tmap2.transform(tpt), tmap2.transform(rhs))
+ cpy.DefDef(ddef)(name, tparams1, vparamss1, tmap2.transform(tpt), tmap2.transform(ddef.rhs))
case blk @ Block(stats, expr) =>
val (tmap1, stats1) = transformDefs(stats)
val expr1 = tmap1.transform(expr)
diff --git a/src/dotty/tools/dotc/ast/Trees.scala b/src/dotty/tools/dotc/ast/Trees.scala
index ff44a48c5..57cbb7f8f 100644
--- a/src/dotty/tools/dotc/ast/Trees.scala
+++ b/src/dotty/tools/dotc/ast/Trees.scala
@@ -334,9 +334,9 @@ object Trees {
}
/** A ValDef or DefDef tree */
- trait ValOrDefDef[-T >: Untyped] extends MemberDef[T] {
+ trait ValOrDefDef[-T >: Untyped] extends MemberDef[T] with WithLazyField[Tree[T]] {
def tpt: Tree[T]
- def rhs: Tree[T]
+ def rhs: Tree[T] = forceIfLazy
}
// ----------- Tree case classes ------------------------------------
@@ -619,17 +619,22 @@ object Trees {
}
/** mods val name: tpt = rhs */
- case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], rhs: Tree[T])
+ case class ValDef[-T >: Untyped] private[ast] (name: TermName, tpt: Tree[T], private var preRhs: Any /*Tree[T] | Lazy[Tree[T]]*/)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = ValDef[T]
assert(isEmpty || tpt != genericEmptyTree)
+ protected def maybeLazy = preRhs
+ protected def maybeLazy_=(x: Any) = 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], rhs: Tree[T])
+ 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]]*/)
extends ValOrDefDef[T] {
type ThisTree[-T >: Untyped] = DefDef[T]
assert(tpt != genericEmptyTree)
+ protected def maybeLazy = preRhs
+ protected def maybeLazy_=(x: Any) = preRhs = x
}
/** mods class name template or
@@ -652,9 +657,12 @@ object Trees {
}
/** extends parents { self => body } */
- case class Template[-T >: Untyped] private[ast] (constr: DefDef[T], parents: List[Tree[T]], self: ValDef[T], body: List[Tree[T]])
- extends DefTree[T] {
+ 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]]]*/)
+ extends DefTree[T] with WithLazyField[List[Tree[T]]] {
type ThisTree[-T >: Untyped] = Template[T]
+ protected def maybeLazy = preBody
+ protected def maybeLazy_=(x: Any) = preBody = x
+ def body: List[Tree[T]] = forceIfLazy
}
/** import expr.selectors
@@ -746,6 +754,33 @@ object Trees {
if (buf != null) buf.toList else trees
}
+ // ----- Lazy trees and tree sequences
+
+ /** A tree that can have a lazy field
+ * The field is represented by some private `var` which is
+ * proxied by the `maybeLazy` accessors. Forcing the field will
+ * set the `var` to the underlying value.
+ */
+ trait WithLazyField[+T] {
+ protected def maybeLazy: Any
+ protected def maybeLazy_=(x: Any): Unit
+ def forceIfLazy: T = maybeLazy match {
+ case lzy: Lazy[T] =>
+ val x = lzy.complete
+ maybeLazy = x
+ x
+ case x: T @ unchecked => x
+ }
+ }
+
+ /** A base trait for lazy tree fields.
+ * These can be instantiated with Lazy instances which
+ * can delay tree construction until the field is first demanded.
+ */
+ trait Lazy[T] {
+ def complete: T
+ }
+
// ----- Generic Tree Instances, inherited from `tpt` and `untpd`.
abstract class Instance[T >: Untyped <: Type] extends DotClass { inst =>
@@ -1114,16 +1149,16 @@ object Trees {
cpy.UnApply(tree)(transform(fun), transform(implicits), transform(patterns))
case EmptyValDef =>
tree
- case tree @ ValDef(name, tpt, rhs) =>
+ case tree @ ValDef(name, tpt, _) =>
val tpt1 = transform(tpt)
- val rhs1 = transform(rhs)
- cpy.ValDef(tree)(name, tpt1, rhs1)
- case tree @ DefDef(name, tparams, vparamss, tpt, rhs) =>
- cpy.DefDef(tree)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(rhs))
+ val rhs1 = transform(tree.rhs)
+ cpy.ValDef(tree)(name, transform(tpt1), transform(rhs1))
+ case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
+ cpy.DefDef(tree)(name, transformSub(tparams), vparamss mapConserve (transformSub(_)), transform(tpt), transform(tree.rhs))
case tree @ TypeDef(name, rhs) =>
cpy.TypeDef(tree)(name, transform(rhs), tree.tparams)
- case Template(constr, parents, self, body) =>
- cpy.Template(tree)(transformSub(constr), transform(parents), transformSub(self), transformStats(body))
+ case tree @ Template(constr, parents, self, _) =>
+ cpy.Template(tree)(transformSub(constr), transform(parents), transformSub(self), transformStats(tree.body))
case Import(expr, selectors) =>
cpy.Import(tree)(transform(expr), selectors)
case PackageDef(pid, stats) =>
@@ -1213,14 +1248,14 @@ object Trees {
this(x, trees)
case UnApply(fun, implicits, patterns) =>
this(this(this(x, fun), implicits), patterns)
- case ValDef(name, tpt, rhs) =>
- this(this(x, tpt), rhs)
- case DefDef(name, tparams, vparamss, tpt, rhs) =>
- this(this((this(x, tparams) /: vparamss)(apply), tpt), rhs)
+ case tree @ ValDef(name, tpt, _) =>
+ this(this(x, tpt), tree.rhs)
+ case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
+ this(this((this(x, tparams) /: vparamss)(apply), tpt), tree.rhs)
case TypeDef(name, rhs) =>
this(x, rhs)
- case Template(constr, parents, self, body) =>
- this(this(this(this(x, constr), parents), self), body)
+ case tree @ Template(constr, parents, self, _) =>
+ this(this(this(this(x, constr), parents), self), tree.body)
case Import(expr, selectors) =>
this(x, expr)
case PackageDef(pid, stats) =>
diff --git a/src/dotty/tools/dotc/ast/tpd.scala b/src/dotty/tools/dotc/ast/tpd.scala
index 52a617ea2..49358a1c0 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: Tree = EmptyTree)(implicit ctx: Context): ValDef =
+ def ValDef(sym: TermSymbol, rhs: Any /*Tree | Lazy[Tree]*/ = 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 =
diff --git a/src/dotty/tools/dotc/ast/untpd.scala b/src/dotty/tools/dotc/ast/untpd.scala
index dfff17514..d7791bfa5 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: Tree): ValDef = new ValDef(name, tpt, rhs)
- def DefDef(name: TermName, tparams: List[TypeDef], vparamss: List[List[ValDef]], tpt: Tree, rhs: Tree): DefDef = new DefDef(name, tparams, vparamss, tpt, rhs)
+ 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 TypeDef(name: TypeName, rhs: Tree): TypeDef = new TypeDef(name, rhs)
- def Template(constr: DefDef, parents: List[Tree], self: ValDef, body: List[Tree]): Template = new Template(constr, parents, self, body)
+ def Template(constr: DefDef, parents: List[Tree], self: ValDef, body:Any /* List[Tree] | lazy[List[Tree]]*/): 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)
diff --git a/src/dotty/tools/dotc/printing/RefinedPrinter.scala b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
index 43dbef890..d6dfd7db0 100644
--- a/src/dotty/tools/dotc/printing/RefinedPrinter.scala
+++ b/src/dotty/tools/dotc/printing/RefinedPrinter.scala
@@ -312,17 +312,17 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
toTextLocal(extractor) ~
"(" ~ toTextGlobal(patterns, ", ") ~ ")" ~
("(" ~ toTextGlobal(implicits, ", ") ~ ")" provided implicits.nonEmpty)
- case tree @ ValDef(name, tpt, rhs) =>
+ case tree @ ValDef(name, tpt, _) =>
dclTextOr {
modText(tree.mods, if (tree.mods is Mutable) "var" else "val") ~~ nameIdText(tree) ~
optAscription(tpt)
- } ~ optText(rhs)(" = " ~ _)
- case tree @ DefDef(name, tparams, vparamss, tpt, rhs) =>
+ } ~ optText(tree.rhs)(" = " ~ _)
+ case tree @ DefDef(name, tparams, vparamss, tpt, _) =>
atOwner(tree) {
dclTextOr {
val first = modText(tree.mods, "def") ~~ nameIdText(tree) ~ tparamsText(tparams)
addVparamssText(first, vparamss) ~ optAscription(tpt)
- } ~ optText(rhs)(" = " ~ _)
+ } ~ optText(tree.rhs)(" = " ~ _)
}
case tree @ TypeDef(name, rhs) =>
atOwner(tree) {
@@ -341,9 +341,9 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
typeDefText(optText(rhs)(" = " ~ _))
}
}
- case Template(constr @ DefDef(_, tparams, vparamss, _, rhs), parents, self, stats) =>
+ case impl @ Template(constr @ DefDef(_, tparams, vparamss, _, _), parents, self, _) =>
val tparamsTxt = tparamsText(tparams)
- val primaryConstrs = if (rhs.isEmpty) Nil else constr :: Nil
+ val primaryConstrs = if (constr.rhs.isEmpty) Nil else constr :: Nil
val prefix: Text =
if (vparamss.isEmpty || primaryConstrs.nonEmpty) tparamsTxt
else {
@@ -356,7 +356,7 @@ class RefinedPrinter(_ctx: Context) extends PlainPrinter(_ctx) {
val selfName = if (self.name == nme.WILDCARD) "this" else self.name.toString
(selfName ~ optText(self.tpt)(": " ~ _) ~ " =>").close
} provided !self.isEmpty
- val bodyText = "{" ~~ selfText ~~ toTextGlobal(primaryConstrs ::: stats, "\n") ~ "}"
+ val bodyText = "{" ~~ selfText ~~ toTextGlobal(primaryConstrs ::: impl.body, "\n") ~ "}"
prefix ~~ (" extends" provided ownerIsClass) ~~ parentsText ~~ bodyText
case Import(expr, selectors) =>
def selectorText(sel: Tree): Text = sel match {
diff --git a/src/dotty/tools/dotc/transform/Constructors.scala b/src/dotty/tools/dotc/transform/Constructors.scala
index d68f20696..f61ee68b9 100644
--- a/src/dotty/tools/dotc/transform/Constructors.scala
+++ b/src/dotty/tools/dotc/transform/Constructors.scala
@@ -149,14 +149,14 @@ class Constructors extends MiniPhaseTransform with SymTransformer { thisTransfor
def splitStats(stats: List[Tree]): Unit = stats match {
case stat :: stats1 =>
stat match {
- case stat @ ValDef(name, tpt, rhs) if !stat.symbol.is(Lazy) =>
+ case stat @ ValDef(name, tpt, _) if !stat.symbol.is(Lazy) =>
val sym = stat.symbol
if (isRetained(sym)) {
- if (!rhs.isEmpty && !isWildcardArg(rhs))
- constrStats += Assign(ref(sym), intoConstr(rhs)).withPos(stat.pos)
+ if (!stat.rhs.isEmpty && !isWildcardArg(stat.rhs))
+ constrStats += Assign(ref(sym), intoConstr(stat.rhs)).withPos(stat.pos)
clsStats += cpy.ValDef(stat)(rhs = EmptyTree)
}
- else if (!rhs.isEmpty) {
+ else if (!stat.rhs.isEmpty) {
sym.copySymDenotation(
initFlags = sym.flags &~ Private,
owner = constr.symbol).installAfter(thisTransform)
diff --git a/src/dotty/tools/dotc/transform/LazyVals.scala b/src/dotty/tools/dotc/transform/LazyVals.scala
index dde086089..87644d2f9 100644
--- a/src/dotty/tools/dotc/transform/LazyVals.scala
+++ b/src/dotty/tools/dotc/transform/LazyVals.scala
@@ -83,7 +83,8 @@ class LazyVals extends MiniPhaseTransform with SymTransformer {
* dotty.runtime(eg dotty.runtime.LazyInt)
*/
def transformLocalValDef(x: ValDef)(implicit ctx: Context) = x match {
- case x@ValDef(name, tpt, valueInitter) =>
+ case ValDef(name, tpt, _) =>
+ val valueInitter = x.rhs
val holderName = ctx.freshName(name.toString + StdNames.nme.LAZY_LOCAL).toTermName
val initName = ctx.freshName(name.toString + StdNames.nme.LAZY_LOCAL_INIT).toTermName
val tpe = x.tpe.widen
@@ -162,7 +163,7 @@ class LazyVals extends MiniPhaseTransform with SymTransformer {
}
def transformFieldValDefNonVolatile(x: ValDef)(implicit ctx: Context) = x match {
- case x@ValDef(name, tpt, rhs) if (x.mods is Flags.Lazy) =>
+ case ValDef(name, tpt, _) if (x.mods is Flags.Lazy) =>
val claz = x.symbol.owner.asClass
val tpe = x.tpe.widen
assert(!(x.mods is Flags.Mutable))
@@ -171,17 +172,16 @@ class LazyVals extends MiniPhaseTransform with SymTransformer {
val containerTree = ValDef(containerSymbol, initValue(tpe))
if (x.tpe.isNotNull && tpe <:< defn.AnyRefType) { // can use 'null' value instead of flag
- val slowPath = DefDef(x.symbol.asTerm, mkDefNonThreadSafeNonNullable(containerSymbol, rhs))
+ val slowPath = DefDef(x.symbol.asTerm, mkDefNonThreadSafeNonNullable(containerSymbol, x.rhs))
Thicket(List(containerTree, slowPath))
}
else {
val flagName = ctx.freshName(name.toString + StdNames.nme.BITMAP_PREFIX).toTermName
val flagSymbol = ctx.newSymbol(x.symbol.owner, flagName, containerFlags, defn.BooleanType)
val flag = ValDef(flagSymbol, Literal(Constants.Constant(false)))
- val slowPath = DefDef(x.symbol.asTerm, mkNonThreadSafeDef(ref(containerSymbol), ref(flagSymbol), rhs))
+ val slowPath = DefDef(x.symbol.asTerm, mkNonThreadSafeDef(ref(containerSymbol), ref(flagSymbol), x.rhs))
Thicket(List(containerTree, flag, slowPath))
}
-
}
/** Create non-threadsafe lazy accessor equivalent to such code
@@ -281,7 +281,7 @@ class LazyVals extends MiniPhaseTransform with SymTransformer {
}
def transformFieldValDefVolatile(x: ValDef)(implicit ctx: Context) = x match {
- case x@ValDef(name, tpt, rhs) if (x.mods is Flags.Lazy) =>
+ case ValDef(name, tpt, _) if (x.mods is Flags.Lazy) =>
assert(!(x.mods is Flags.Mutable))
val tpe = x.tpe.widen
@@ -334,7 +334,7 @@ class LazyVals extends MiniPhaseTransform with SymTransformer {
val state = Select(ref(helperModule), RLazyVals.Names.state.toTermName)
val cas = Select(ref(helperModule), RLazyVals.Names.cas.toTermName)
- val accessor = mkThreadSafeDef(x.symbol.asTerm, claz, ord, containerSymbol, rhs, tpe, offset, getFlag, state, cas, setFlag, wait)
+ val accessor = mkThreadSafeDef(x.symbol.asTerm, claz, ord, containerSymbol, x.rhs, tpe, offset, getFlag, state, cas, setFlag, wait)
if(flag eq EmptyTree)
Thicket(List(containerTree, accessor))
else Thicket(List(containerTree, flag, accessor))
diff --git a/src/dotty/tools/dotc/transform/MacroTransform.scala b/src/dotty/tools/dotc/transform/MacroTransform.scala
index 3a8bcc920..0f57c3ff5 100644
--- a/src/dotty/tools/dotc/transform/MacroTransform.scala
+++ b/src/dotty/tools/dotc/transform/MacroTransform.scala
@@ -58,12 +58,12 @@ abstract class MacroTransform extends Phase {
tree
case _: PackageDef | _: MemberDef =>
super.transform(tree)(localCtx(tree))
- case Template(constr, parents, self, body) =>
+ case impl @ Template(constr, parents, self, _) =>
cpy.Template(tree)(
transformSub(constr),
transform(parents)(ctx.superCallContext),
transformSelf(self),
- transformStats(body, tree.symbol))
+ transformStats(impl.body, tree.symbol))
case _ =>
super.transform(tree)
}
diff --git a/src/dotty/tools/dotc/transform/RestoreScopes.scala b/src/dotty/tools/dotc/transform/RestoreScopes.scala
index 5f2fd689d..8a6bb15ba 100644
--- a/src/dotty/tools/dotc/transform/RestoreScopes.scala
+++ b/src/dotty/tools/dotc/transform/RestoreScopes.scala
@@ -20,9 +20,9 @@ class RestoreScopes extends MiniPhaseTransform with IdentityDenotTransformer { t
override def phaseName = "restoreScopes"
override def transformTypeDef(tree: TypeDef)(implicit ctx: Context, info: TransformerInfo) = {
- val TypeDef(_, Template(constr, _, _, body)) = tree
+ val TypeDef(_, impl: Template) = tree
val restoredDecls = newScope
- for (stat <- constr :: body)
+ for (stat <- impl.constr :: impl.body)
if (stat.isInstanceOf[MemberDef] && stat.symbol.exists)
restoredDecls.enter(stat.symbol)
val cls = tree.symbol.asClass
diff --git a/src/dotty/tools/dotc/transform/SuperAccessors.scala b/src/dotty/tools/dotc/transform/SuperAccessors.scala
index 0d89e9d74..c4ff6e549 100644
--- a/src/dotty/tools/dotc/transform/SuperAccessors.scala
+++ b/src/dotty/tools/dotc/transform/SuperAccessors.scala
@@ -369,9 +369,9 @@ class SuperAccessors extends MacroTransform with IdentityDenotTransformer { this
}
transformSelect
- case tree @ DefDef(_, _, _, _, rhs) =>
+ case tree: DefDef =>
cpy.DefDef(tree)(
- rhs = if (isMethodWithExtension(sym)) withInvalidOwner(transform(rhs)) else transform(rhs))
+ rhs = if (isMethodWithExtension(sym)) withInvalidOwner(transform(tree.rhs)) else transform(tree.rhs))
case TypeApply(sel @ Select(qual, name), args) =>
mayNeedProtectedAccessor(sel, args, goToSuper = true)
diff --git a/src/dotty/tools/dotc/transform/TailRec.scala b/src/dotty/tools/dotc/transform/TailRec.scala
index b747636c7..2fd0c439c 100644
--- a/src/dotty/tools/dotc/transform/TailRec.scala
+++ b/src/dotty/tools/dotc/transform/TailRec.scala
@@ -83,8 +83,8 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
val sym = tree.symbol
tree match {
- case dd@DefDef(name, tparams, vparamss0, tpt, rhs0)
- if (sym.isEffectivelyFinal) && !((sym is Flags.Accessor) || (rhs0 eq EmptyTree) || (sym is Flags.Label)) =>
+ case dd@DefDef(name, tparams, vparamss0, tpt, _)
+ if (sym.isEffectivelyFinal) && !((sym is Flags.Accessor) || (dd.rhs eq EmptyTree) || (sym is Flags.Label)) =>
val mandatory = sym.hasAnnotation(defn.TailrecAnnotationClass)
atGroupEnd { implicit ctx: Context =>
@@ -104,7 +104,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
// now this speculatively transforms tree and throws away result in many cases
val rhsSemiTransformed = {
val transformer = new TailRecElimination(origMeth, owner, thisTpe, mandatory, label, abstractOverClass = defIsTopLevel)
- val rhs = atGroupEnd(transformer.transform(rhs0)(_))
+ val rhs = atGroupEnd(transformer.transform(dd.rhs)(_))
rewrote = transformer.rewrote
rhs
}
@@ -117,7 +117,7 @@ class TailRec extends MiniPhaseTransform with DenotTransformer with FullParamete
} else {
if (mandatory)
ctx.error("TailRec optimisation not applicable, method not tail recursive", dd.pos)
- rhs0
+ dd.rhs
}
})
}
diff --git a/src/dotty/tools/dotc/typer/Namer.scala b/src/dotty/tools/dotc/typer/Namer.scala
index c522a5998..4bf194f5e 100644
--- a/src/dotty/tools/dotc/typer/Namer.scala
+++ b/src/dotty/tools/dotc/typer/Namer.scala
@@ -436,9 +436,9 @@ class Namer { typer: Typer =>
protected implicit val ctx: Context = localContext(cls).setMode(ictx.mode &~ Mode.InSuperCall)
- val TypeDef(name, impl @ Template(constr, parents, self, body)) = original
+ val TypeDef(name, impl @ Template(constr, parents, self, _)) = original
- val (params, rest) = body span {
+ val (params, rest) = impl.body span {
case td: TypeDef => td.mods is Param
case td: ValDef => td.mods is ParamAccessor
case _ => false
@@ -496,9 +496,9 @@ class Namer { typer: Typer =>
index(rest)(inClassContext(selfInfo))
denot.info = ClassInfo(cls.owner.thisType, cls, parentRefs, decls, selfInfo)
if (cls is Trait) {
- if (body forall isNoInitMember) {
+ if (impl.body forall isNoInitMember) {
cls.setFlag(NoInits)
- if (body forall isPureInterfaceMember)
+ if (impl.body forall isPureInterfaceMember)
cls.setFlag(PureInterface)
}
}
diff --git a/src/dotty/tools/dotc/typer/Typer.scala b/src/dotty/tools/dotc/typer/Typer.scala
index 974a42638..1e93f98f3 100644
--- a/src/dotty/tools/dotc/typer/Typer.scala
+++ b/src/dotty/tools/dotc/typer/Typer.scala
@@ -794,7 +794,8 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val tpt1 = if (tree.tpt.isEmpty) TypeTree(defn.ObjectType) else typedAheadType(tree.tpt)
val refineClsDef = desugar.refinedTypeToClass(tpt1, tree.refinements)
val refineCls = createSymbol(refineClsDef).asClass
- val TypeDef(_, Template(_, _, _, refinements1)) = typed(refineClsDef)
+ val TypeDef(_, impl: Template) = typed(refineClsDef)
+ val refinements1 = impl.body
val seen = mutable.Set[Symbol]()
assert(tree.refinements.length == refinements1.length, s"${tree.refinements} != $refinements1")
def addRefinement(parent: Type, refinement: Tree): Type = {
@@ -866,24 +867,24 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def typedValDef(vdef: untpd.ValDef, sym: Symbol)(implicit ctx: Context) = track("typedValDef") {
- val ValDef(name, tpt, rhs) = vdef
+ val ValDef(name, tpt, _) = vdef
addTypedModifiersAnnotations(vdef, sym)
val tpt1 = typedType(tpt)
- val rhs1 = rhs match {
- case Ident(nme.WILDCARD) => rhs withType tpt1.tpe
- case _ => typedExpr(rhs, tpt1.tpe)
+ val rhs1 = vdef.rhs match {
+ case rhs @ Ident(nme.WILDCARD) => rhs withType tpt1.tpe
+ case rhs => typedExpr(rhs, tpt1.tpe)
}
assignType(cpy.ValDef(vdef)(name, tpt1, rhs1), sym)
}
def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = track("typedDefDef") {
- val DefDef(name, tparams, vparamss, tpt, rhs) = ddef
+ val DefDef(name, tparams, vparamss, tpt, _) = ddef
addTypedModifiersAnnotations(ddef, sym)
val tparams1 = tparams mapconserve (typed(_).asInstanceOf[TypeDef])
val vparamss1 = vparamss nestedMapconserve (typed(_).asInstanceOf[ValDef])
if (sym is Implicit) checkImplicitParamsNotSingletons(vparamss1)
val tpt1 = typedType(tpt)
- val rhs1 = typedExpr(rhs, tpt1.tpe)
+ val rhs1 = typedExpr(ddef.rhs, tpt1.tpe)
assignType(cpy.DefDef(ddef)(name, tparams1, vparamss1, tpt1, rhs1), sym)
//todo: make sure dependent method types do not depend on implicits or by-name params
}
@@ -896,7 +897,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
}
def typedClassDef(cdef: untpd.TypeDef, cls: ClassSymbol)(implicit ctx: Context) = track("typedClassDef") {
- val TypeDef(name, impl @ Template(constr, parents, self, body)) = cdef
+ val TypeDef(name, impl @ Template(constr, parents, self, _)) = cdef
val superCtx = ctx.superCallContext
def typedParent(tree: untpd.Tree): Tree =
if (tree.isType) typedType(tree)(superCtx)
@@ -913,7 +914,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
val parents1 = ensureConstrCall(cls, parentsWithClass)(superCtx)
val self1 = typed(self)(ctx.outer).asInstanceOf[ValDef] // outer context where class members are not visible
val dummy = localDummy(cls, impl)
- val body1 = typedStats(body, dummy)(inClassContext(self1.symbol))
+ val body1 = typedStats(impl.body, dummy)(inClassContext(self1.symbol))
checkNoDoubleDefs(cls)
val impl1 = cpy.Template(impl)(constr1, parents1, self1, body1)
.withType(dummy.nonMemberTermRef)