Skip to content

Commit d62a2c9

Browse files
authored
Merge pull request #1890 from dotty-staging/remove-inlined-fields
Stop emitting fields for inlined fields.
2 parents be64643 + 1cb50ca commit d62a2c9

File tree

2 files changed

+29
-21
lines changed

2 files changed

+29
-21
lines changed

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

Lines changed: 7 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -95,28 +95,15 @@ import Decorators._
9595
def adaptToField(tree: Tree) =
9696
if (tree.isEmpty) tree else tree.ensureConforms(field.info.widen)
9797

98+
val NoFieldNeeded = Lazy | Deferred | JavaDefined | (if (ctx.settings.YnoInline.value) EmptyFlags else Inline)
99+
98100
if (sym.is(Accessor, butNot = NoFieldNeeded))
99101
if (sym.isGetter) {
100-
def skipBlocks(t: Tree): Tree = t match {
101-
case Block(_, t1) => skipBlocks(t1)
102-
case _ => t
103-
}
104-
skipBlocks(tree.rhs) match {
105-
case lit: Literal if sym.is(Final, butNot = Mutable) && isIdempotentExpr(tree.rhs) =>
106-
// duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field
107-
// and instead return the value. This seemingly minor optimization has huge effect on initialization
108-
// order and the values that can be observed during superconstructor call
109-
110-
// see remark about idempotency in PostTyper#normalizeTree
111-
cpy.DefDef(tree)(rhs = lit)
112-
case _ =>
113-
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
114-
if (isWildcardArg(rhs)) rhs = EmptyTree
115-
116-
val fieldDef = transformFollowing(ValDef(field, adaptToField(rhs)))
117-
val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field))(ctx.withOwner(sym), info))
118-
Thicket(fieldDef, getterDef)
119-
}
102+
var rhs = tree.rhs.changeOwnerAfter(sym, field, thisTransform)
103+
if (isWildcardArg(rhs)) rhs = EmptyTree
104+
val fieldDef = transformFollowing(ValDef(field, adaptToField(rhs)))
105+
val getterDef = cpy.DefDef(tree)(rhs = transformFollowingDeep(ref(field))(ctx.withOwner(sym), info))
106+
Thicket(fieldDef, getterDef)
120107
} else if (sym.isSetter) {
121108
if (!sym.is(ParamAccessor)) { val Literal(Constant(())) = tree.rhs } // this is intended as an assertion
122109
field.setFlag(Mutable) // necessary for vals mixed in from Scala2 traits
@@ -127,5 +114,4 @@ import Decorators._
127114
// neither getters nor setters
128115
else tree
129116
}
130-
private val NoFieldNeeded = Lazy | Deferred | JavaDefined
131117
}

compiler/src/dotty/tools/dotc/typer/Typer.scala

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1173,6 +1173,7 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
11731173
if (sym.is(Inline, butNot = DeferredOrParamAccessor))
11741174
checkInlineConformant(rhs1, em"right-hand side of inline $sym")
11751175
patchIfLazy(vdef1)
1176+
patchFinalVals(vdef1)
11761177
vdef1
11771178
}
11781179

@@ -1185,6 +1186,27 @@ class Typer extends Namer with TypeAssigner with Applications with Implicits wit
11851186
patch(Position(toUntyped(vdef).pos.start), "@volatile ")
11861187
}
11871188

1189+
/** Adds inline to final vals with idempotent rhs
1190+
*
1191+
* duplicating scalac behavior: for final vals that have rhs as constant, we do not create a field
1192+
* and instead return the value. This seemingly minor optimization has huge effect on initialization
1193+
* order and the values that can be observed during superconstructor call
1194+
*
1195+
* see remark about idempotency in PostTyper#normalizeTree
1196+
*/
1197+
private def patchFinalVals(vdef: ValDef)(implicit ctx: Context): Unit = {
1198+
def isFinalInlinableVal(sym: Symbol): Boolean = {
1199+
sym.is(Final, butNot = Mutable) &&
1200+
isIdempotentExpr(vdef.rhs) /* &&
1201+
ctx.scala2Mode (stay compatible with Scala2 for now) */
1202+
}
1203+
val sym = vdef.symbol
1204+
sym.info match {
1205+
case info: ConstantType if isFinalInlinableVal(sym) && !ctx.settings.YnoInline.value => sym.setFlag(Inline)
1206+
case _ =>
1207+
}
1208+
}
1209+
11881210
def typedDefDef(ddef: untpd.DefDef, sym: Symbol)(implicit ctx: Context) = track("typedDefDef") {
11891211
val DefDef(name, tparams, vparamss, tpt, _) = ddef
11901212
completeAnnotations(ddef, sym)

0 commit comments

Comments
 (0)