@@ -111,7 +111,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
111
111
112
112
113
113
class FieldMemoization (accessorOrField : Symbol , site : Symbol ) {
114
- private val tp = fieldTypeOfAccessorIn(accessorOrField, site.thisType)
114
+ val tp = fieldTypeOfAccessorIn(accessorOrField, site.thisType)
115
115
// not stored, no side-effect
116
116
val pureConstant = tp.isInstanceOf [ConstantType ]
117
117
@@ -176,8 +176,9 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
176
176
177
177
// strict, memoized accessors will receive an implementation in first real class to extend this trait
178
178
origDecls.foreach { accessor => if (accessor hasFlag ACCESSOR ) {
179
+ val fieldMemoization = fieldMemoizationIn(accessor, clazz)
179
180
// check flags before calling makeNotPrivate
180
- val memoizedGetter = ! (accessor hasFlag (DEFERRED | LAZY )) && fieldMemoizationIn(accessor, clazz).stored
181
+ val accessorUnderConsideration = ! (accessor hasFlag (DEFERRED | LAZY ))
181
182
182
183
// destructively mangle accessor's name (which may cause rehashing of decls), also sets flags
183
184
if (accessor hasFlag PRIVATE ) accessor makeNotPrivate clazz
@@ -194,12 +195,12 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
194
195
// (not sure why this only problem only arose when we started setting the notPROTECTED flag)
195
196
196
197
// derive trait setter after calling makeNotPrivate (so that names are mangled consistently)
197
- if (memoizedGetter ) {
198
+ if (accessorUnderConsideration && fieldMemoization.stored ) {
198
199
setTraitAccessorFlags(accessor)
199
200
200
201
if (accessor hasFlag STABLE ) // TODO: check isGetter?
201
202
newSetters += newTraitSetter(accessor, clazz)
202
- }
203
+ } else if (fieldMemoization.pureConstant) setTraitAccessorFlags(accessor) // TODO: remove when we no longer care about producing identical bytecode
203
204
}}
204
205
205
206
if (newSetters nonEmpty) {
@@ -348,6 +349,12 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
348
349
349
350
val accessorsAndFieldsNeedingTrees = clazz.info.decls.toList.filter(checkAndClearNeedsTrees)
350
351
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
+
351
358
// println(s"accessorsAndFieldsNeedingTrees: $accessorsAndFieldsNeedingTrees")
352
359
def setterBody (setter : Symbol ): Tree = {
353
360
// trait setter in trait
@@ -360,7 +367,7 @@ abstract class Fields extends InfoTransform with ast.TreeDSL with TypingTransfor
360
367
361
368
accessorsAndFieldsNeedingTrees map {
362
369
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 ]
364
371
case field => assert(field.isValue && ! field.isMethod, s " Expecting field, got $field" )
365
372
localTyper.typedPos(field.pos)(ValDef (field)).asInstanceOf [ValDef ]
366
373
}
0 commit comments