Skip to content

Commit

Permalink
Memoize should produce constant DefDefs for constant final vals.
Browse files Browse the repository at this point in the history
It produced just the right hand side literal before.
  • Loading branch information
odersky authored and DarkDimius committed Sep 14, 2015
1 parent ef6e2e9 commit 56dfb4e
Showing 1 changed file with 10 additions and 11 deletions.
21 changes: 10 additions & 11 deletions src/dotty/tools/dotc/transform/Memoize.scala
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down

0 comments on commit 56dfb4e

Please sign in to comment.