Skip to content

Commit baf568d

Browse files
committed
produce identical bytecode for constant trait val getters
I couldn't bring myself to emit the unused fields that we used to emit for constant vals, even though the getters immediately return the constant, and thus the field goes unused. In the next version, there's no need to synthesize impls for these in subclasses -- the getter can be implemented in the interface.
1 parent 874f48b commit baf568d

File tree

1 file changed

+12
-5
lines changed

1 file changed

+12
-5
lines changed

src/compiler/scala/tools/nsc/transform/Fields.scala

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -111,7 +111,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
111111

112112

113113
class FieldMemoization(accessorOrField: Symbol, site: Symbol) {
114-
private val tp = fieldTypeOfAccessorIn(accessorOrField, site.thisType)
114+
val tp = fieldTypeOfAccessorIn(accessorOrField, site.thisType)
115115
// not stored, no side-effect
116116
val pureConstant = tp.isInstanceOf[ConstantType]
117117

@@ -176,8 +176,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
176176

177177
// strict, memoized accessors will receive an implementation in first real class to extend this trait
178178
origDecls.foreach { accessor => if (accessor hasFlag ACCESSOR) {
179+
val fieldMemoization = fieldMemoizationIn(accessor, clazz)
179180
// check flags before calling makeNotPrivate
180-
val memoizedGetter = !(accessor hasFlag (DEFERRED | LAZY)) && fieldMemoizationIn(accessor, clazz).stored
181+
val accessorUnderConsideration = !(accessor hasFlag (DEFERRED | LAZY))
181182

182183
// destructively mangle accessor's name (which may cause rehashing of decls), also sets flags
183184
if (accessor hasFlag PRIVATE) accessor makeNotPrivate clazz
@@ -194,12 +195,12 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
194195
// (not sure why this only problem only arose when we started setting the notPROTECTED flag)
195196

196197
// derive trait setter after calling makeNotPrivate (so that names are mangled consistently)
197-
if (memoizedGetter) {
198+
if (accessorUnderConsideration && fieldMemoization.stored) {
198199
setTraitAccessorFlags(accessor)
199200

200201
if (accessor hasFlag STABLE) // TODO: check isGetter?
201202
newSetters += newTraitSetter(accessor, clazz)
202-
}
203+
} else if (fieldMemoization.pureConstant) setTraitAccessorFlags(accessor) // TODO: remove when we no longer care about producing identical bytecode
203204
}}
204205

205206
if (newSetters nonEmpty) {
@@ -348,6 +349,12 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
348349

349350
val accessorsAndFieldsNeedingTrees = clazz.info.decls.toList.filter(checkAndClearNeedsTrees)
350351

352+
def getterBody(getter: Symbol): Tree = {
353+
val fieldMemoization = fieldMemoizationIn(getter, clazz)
354+
if (fieldMemoization.pureConstant) gen.mkAttributedQualifier(fieldMemoization.tp) // TODO: drop when we no longer care about producing identical bytecode
355+
else fieldAccess(getter)
356+
}
357+
351358
// println(s"accessorsAndFieldsNeedingTrees: $accessorsAndFieldsNeedingTrees")
352359
def setterBody(setter: Symbol): Tree = {
353360
// trait setter in trait
@@ -360,7 +367,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
360367

361368
accessorsAndFieldsNeedingTrees map {
362369
case setter if setter.isSetter => localTyper.typedPos(setter.pos)(DefDef(setter, setterBody(setter))).asInstanceOf[DefDef]
363-
case getter if getter.isAccessor => localTyper.typedPos(getter.pos)(DefDef(getter, fieldAccess(getter))).asInstanceOf[DefDef]
370+
case getter if getter.isAccessor => localTyper.typedPos(getter.pos)(DefDef(getter, getterBody(getter))).asInstanceOf[DefDef]
364371
case field => assert(field.isValue && !field.isMethod, s"Expecting field, got $field")
365372
localTyper.typedPos(field.pos)(ValDef(field)).asInstanceOf[ValDef]
366373
}

0 commit comments

Comments
 (0)