diff options
author | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-08-24 15:10:04 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-09-14 13:36:14 +0200 |
commit | f1f141eb04fa79bdee5a3b2aa354c488523ac199 (patch) | |
tree | f93b5f33bb75deca1801cc0e7e226824b6fc8cad /src | |
parent | 2a2940e4a92508b767885c1c5ef63b09b564aa43 (diff) | |
download | dotty-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.scala | 14 |
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)) |