Skip to content

Commit 8f47f16

Browse files
committed
#676 generate less code for lazy vals
Modules which are entirely synthetic now are eager This fix additionally makes inner objects of other objects remain static classes, instead of becoming lazy vals.
1 parent 65b0c37 commit 8f47f16

File tree

1 file changed

+33
-13
lines changed

1 file changed

+33
-13
lines changed

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

Lines changed: 33 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -46,18 +46,38 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
4646
* before this phase starts processing same tree */
4747
override def runsAfter = Set(classOf[Mixin])
4848

49-
override def transformDefDef(tree: DefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
50-
if (!(tree.symbol is Flags.Lazy) || tree.symbol.owner.is(Flags.Trait)) tree
51-
else {
52-
val isField = tree.symbol.owner.isClass
53-
54-
if (isField) {
55-
if (tree.symbol.isVolatile || tree.symbol.is(Flags.Module)) transformMemberDefVolatile(tree)
56-
else transformMemberDefNonVolatile(tree)
57-
}
58-
else transformLocalDef(tree)
49+
override def transformDefDef(tree: tpd.DefDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree =
50+
transformLazyVal(tree)
51+
52+
53+
override def transformValDef(tree: tpd.ValDef)(implicit ctx: Context, info: TransformerInfo): tpd.Tree = {
54+
transformLazyVal(tree)
55+
}
56+
57+
def transformLazyVal(tree: ValOrDefDef)(implicit ctx: Context, info: TransformerInfo): Tree = {
58+
val sym = tree.symbol
59+
if (!(sym is Flags.Lazy) || sym.owner.is(Flags.Trait) || (sym.isStatic && sym.is(Flags.Module))) tree
60+
else {
61+
62+
val isField = sym.owner.isClass
63+
64+
if (isField) {
65+
if (sym.isVolatile ||
66+
(sym.is(Flags.Module) && !sym.is(Flags.Synthetic))) // companion class is synthesized. Should be threadsafe to
67+
// make inner lazy vals thread safe
68+
transformMemberDefVolatile(tree)
69+
else if (sym.is(Flags.Module)) { // synthetic module
70+
val holderSymbol = ctx.newSymbol(sym.owner, sym.asTerm.name ++ nme.LAZY_LOCAL,
71+
Flags.Synthetic, sym.info.widen.resultType).enteredAfter(this)
72+
val field = ValDef(holderSymbol, tree.rhs.changeOwnerAfter(sym, holderSymbol, this))
73+
val getter = DefDef(sym.asTerm, ref(holderSymbol))
74+
Thicket(field, getter)
75+
}
76+
else transformMemberDefNonVolatile(tree)
5977
}
78+
else transformLocalDef(tree)
6079
}
80+
}
6181

6282

6383
/** Append offset fields to companion objects
@@ -82,7 +102,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
82102
* with a LazyHolder from
83103
* dotty.runtime(eg dotty.runtime.LazyInt)
84104
*/
85-
def transformLocalDef(x: DefDef)(implicit ctx: Context) = {
105+
def transformLocalDef(x: ValOrDefDef)(implicit ctx: Context) = {
86106
val valueInitter = x.rhs
87107
val holderName = ctx.freshName(x.name ++ StdNames.nme.LAZY_LOCAL).toTermName
88108
val initName = ctx.freshName(x.name ++ StdNames.nme.LAZY_LOCAL_INIT).toTermName
@@ -172,7 +192,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
172192
If(cond, init, exp)
173193
}
174194

175-
def transformMemberDefNonVolatile(x: DefDef)(implicit ctx: Context) = {
195+
def transformMemberDefNonVolatile(x: ValOrDefDef)(implicit ctx: Context) = {
176196
val claz = x.symbol.owner.asClass
177197
val tpe = x.tpe.widen.resultType.widen
178198
assert(!(x.mods is Flags.Mutable))
@@ -293,7 +313,7 @@ class LazyVals extends MiniPhaseTransform with IdentityDenotTransformer {
293313
DefDef(methodSymbol, Block(resultDef :: retryDef :: flagDef :: cycle :: Nil, ref(resultSymbol)))
294314
}
295315

296-
def transformMemberDefVolatile(x: DefDef)(implicit ctx: Context) = {
316+
def transformMemberDefVolatile(x: ValOrDefDef)(implicit ctx: Context) = {
297317
assert(!(x.mods is Flags.Mutable))
298318

299319
val tpe = x.tpe.widen.resultType.widen

0 commit comments

Comments
 (0)