diff options
author | Martin Odersky <odersky@gmail.com> | 2015-09-08 10:41:51 +0200 |
---|---|---|
committer | Dmitry Petrashko <dmitry.petrashko@gmail.com> | 2015-09-14 13:38:16 +0200 |
commit | 56dfb4e953e42e1defd20d58fb671c6ae802e91a (patch) | |
tree | a0e80f40d05c09df455022dee4c5d60d631215a4 /src | |
parent | ef6e2e9c6017675ffc2fefaaf2b217d05681a4c2 (diff) | |
download | dotty-56dfb4e953e42e1defd20d58fb671c6ae802e91a.tar.gz dotty-56dfb4e953e42e1defd20d58fb671c6ae802e91a.tar.bz2 dotty-56dfb4e953e42e1defd20d58fb671c6ae802e91a.zip |
Memoize should produce constant DefDefs for constant final vals.
It produced just the right hand side literal before.
Diffstat (limited to 'src')
-rw-r--r-- | src/dotty/tools/dotc/transform/Memoize.scala | 21 |
1 files changed, 10 insertions, 11 deletions
diff --git a/src/dotty/tools/dotc/transform/Memoize.scala b/src/dotty/tools/dotc/transform/Memoize.scala index a2954b4a2..53f40044f 100644 --- a/src/dotty/tools/dotc/transform/Memoize.scala +++ b/src/dotty/tools/dotc/transform/Memoize.scala @@ -71,20 +71,19 @@ import Decorators._ 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 Block(_, t1) => skipBlocks(t1) 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)) + skipBlocks(tree.rhs) match { + case lit: Literal if sym.is(Final) && isIdempotentExpr(tree.rhs) => + // see remark about idempotency in PostTyper#normalizeTree + cpy.DefDef(tree)(rhs = lit) + case _ => + 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)) - Thicket(fieldDef, getterDef) + Thicket(fieldDef, getterDef) } } else if (sym.isSetter) { if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs } // this is intended as an assertion |