aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorDmitry Petrashko <dmitry.petrashko@gmail.com>2015-08-24 15:10:04 +0200
committerDmitry Petrashko <dmitry.petrashko@gmail.com>2015-09-14 13:36:14 +0200
commitf1f141eb04fa79bdee5a3b2aa354c488523ac199 (patch)
treef93b5f33bb75deca1801cc0e7e226824b6fc8cad /src
parent2a2940e4a92508b767885c1c5ef63b09b564aa43 (diff)
downloaddotty-f1f141eb04fa79bdee5a3b2aa354c488523ac199.tar.gz
dotty-f1f141eb04fa79bdee5a3b2aa354c488523ac199.tar.bz2
dotty-f1f141eb04fa79bdee5a3b2aa354c488523ac199.zip
Memoize: duplicate scala2 behaviour: don't create fields for final vals.
This affect initialisation order and we rely on artifacts of initialisation order in Dotty.
Diffstat (limited to 'src')
-rw-r--r--src/dotty/tools/dotc/transform/Memoize.scala14
1 files changed, 12 insertions, 2 deletions
diff --git a/src/dotty/tools/dotc/transform/Memoize.scala b/src/dotty/tools/dotc/transform/Memoize.scala
index 63466dc46..a2954b4a2 100644
--- a/src/dotty/tools/dotc/transform/Memoize.scala
+++ b/src/dotty/tools/dotc/transform/Memoize.scala
@@ -70,13 +70,23 @@ import Decorators._
lazy val field = sym.field.orElse(newField).asTerm
if (sym.is(Accessor, butNot = NoFieldNeeded))
if (sym.isGetter) {
+ def skipBlocks(t: Tree): Tree = t match {
+ case Block(a, b) if a.forall(isIdempotentExpr) => skipBlocks(b)
+ case _ => t
+ }
+ if (sym.is(Flags.Final) && skipBlocks(tree.rhs).isInstanceOf[Literal])
+ // duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field
+ // and instead return the value. This seemingly minor optimization has huge effect on initialization
+ // order and the values that can be observed during superconstructor call
+ tree
+ else {
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
if (isWildcardArg(rhs)) rhs = EmptyTree
val fieldDef = transformFollowing(ValDef(field, rhs))
- val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field))(ctx.withOwner(sym), info))
+ val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field))(ctx.withOwner(sym), info))
Thicket(fieldDef, getterDef)
}
- else if (sym.isSetter) {
+ } else if (sym.isSetter) {
if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs } // this is intended as an assertion
val initializer = Assign(ref(field), ref(tree.vparamss.head.head.symbol))
cpy.DefDef(tree)(rhs = transformFollowingDeep(initializer)(ctx.withOwner(sym), info))