Skip to content

Commit 6e08844

Browse files
committed
Memoize should produce constant DefDefs for constant final vals.
It produced just the right hand side literal before.
1 parent b888f66 commit 6e08844

File tree

1 file changed

+11
-12
lines changed

1 file changed

+11
-12
lines changed

src/dotty/tools/dotc/transform/Memoize.scala

Lines changed: 11 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -71,20 +71,19 @@ import Decorators._
7171
if (sym.is(Accessor, butNot = NoFieldNeeded))
7272
if (sym.isGetter) {
7373
def skipBlocks(t: Tree): Tree = t match {
74-
case Block(a, b) if a.forall(isIdempotentExpr) => skipBlocks(b)
74+
case Block(_, t1) => skipBlocks(t1)
7575
case _ => t
7676
}
77-
if (sym.is(Flags.Final) && skipBlocks(tree.rhs).isInstanceOf[Literal])
78-
// duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field
79-
// and instead return the value. This seemingly minor optimization has huge effect on initialization
80-
// order and the values that can be observed during superconstructor call
81-
tree
82-
else {
83-
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
84-
if (isWildcardArg(rhs)) rhs = EmptyTree
85-
val fieldDef = transformFollowing(ValDef(field, rhs))
86-
val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field)))
87-
Thicket(fieldDef, getterDef)
77+
skipBlocks(tree.rhs) match {
78+
case lit: Literal if sym.is(Final) && isIdempotentExpr(tree.rhs) =>
79+
// see remark about idempotency in PostTyper#normalizeTree
80+
cpy.DefDef(tree)(rhs = lit)
81+
case _ =>
82+
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
83+
if (isWildcardArg(rhs)) rhs = EmptyTree
84+
val fieldDef = transformFollowing(ValDef(field, rhs))
85+
val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field)))
86+
Thicket(fieldDef, getterDef)
8887
}
8988
}
9089
else if (sym.isSetter) {

0 commit comments

Comments
 (0)