@@ -149,12 +149,12 @@ trait MethodSynthesis {
149
149
val getter = Getter (tree)
150
150
val getterSym = getter.createAndEnterSymbol()
151
151
// Create the setter if necessary.
152
- if (mods.isMutable )
152
+ if (getter.needsSetter )
153
153
Setter (tree).createAndEnterSymbol()
154
154
155
155
// Create a field if the getter requires storage, otherwise,
156
156
// the getter's abstract and the tree gets the getter's symbol.
157
- if (getter.noFieldNeeded ) getterSym setPos tree.pos
157
+ if (getter.noFieldHere ) getterSym setPos tree.pos
158
158
else enterStrictVal(tree)
159
159
}
160
160
@@ -302,14 +302,16 @@ trait MethodSynthesis {
302
302
def derivedSym : Symbol = tree.symbol
303
303
def derivedTree : Tree = EmptyTree
304
304
305
- // - abstract vals have no value and thus need for a field (until they become concrete, potentially)
306
- // - traits store the RHS of the field in the getter;
307
- // constructors will move the assignment to the constructor, abstracting over the field using the field setter
308
- // - lazy or not, a val that stores a statically known value (unit / ConstantType) doesn't need a field either,
309
- // although the lazy value will need to consult the init bitmap to make sure the lazy compute method is only run once
310
- def noFieldNeeded = isDeferred ||
311
- derivedSym.owner.isTrait ||
312
- typeNeedsNoStorage(basisSym.tpe)
305
+ // No field for these vals:
306
+ // - abstract vals have no value we could store (until they become concrete, potentially)
307
+ // - a concrete val with a statically known value (Unit / ConstantType)
308
+ // performs its side effect according to lazy/strict semantics, but doesn't need to store its value
309
+ // each access will "evaluate" the RHS (a literal) again
310
+ // - concrete vals in traits don't yield a field here either (their getter's RHS has the initial value)
311
+ // Constructors will move the assignment to the constructor, abstracting over the field using the field setter,
312
+ // and Mixin will add a field to the class that mixes in the trait, implementing the accessors in terms of it
313
+ def noFieldHere = nothingToMemoize || derivedSym.owner.isTrait
314
+ protected def nothingToMemoize = isDeferred || typeNeedsNoStorage(basisSym.tpe)
313
315
314
316
def isSetter = false
315
317
def isDeferred = mods.isDeferred
@@ -334,7 +336,7 @@ trait MethodSynthesis {
334
336
}
335
337
}
336
338
sealed trait DerivedGetter extends DerivedFromValDef {
337
- // TODO
339
+ def needsSetter = mods.isMutable || (derivedSym.owner.isTrait && ! nothingToMemoize)
338
340
}
339
341
sealed trait DerivedSetter extends DerivedFromValDef {
340
342
override def isSetter = true
@@ -343,7 +345,7 @@ trait MethodSynthesis {
343
345
case _ => NoSymbol
344
346
}
345
347
private def setterRhs =
346
- if (noFieldNeeded || derivedSym.isOverloaded) EmptyTree
348
+ if (noFieldHere || derivedSym.isOverloaded) EmptyTree
347
349
else Assign (fieldSelection, Ident (setterParam))
348
350
349
351
private def setterDef = DefDef (derivedSym, setterRhs)
@@ -386,7 +388,8 @@ trait MethodSynthesis {
386
388
}
387
389
case class Getter (tree : ValDef ) extends BaseGetter (tree) {
388
390
override def derivedSym = if (isDeferred) basisSym else basisSym.getterIn(enclClass)
389
- private def derivedRhs = if (noFieldNeeded) tree.rhs else fieldSelection
391
+ private def derivedRhs = if (noFieldHere) tree.rhs else fieldSelection
392
+
390
393
private def derivedTpt = {
391
394
// For existentials, don't specify a type for the getter, even one derived
392
395
// from the symbol! This leads to incompatible existentials for the field and
@@ -434,7 +437,7 @@ trait MethodSynthesis {
434
437
override def derivedTree : DefDef = {
435
438
val ValDef (_, _, tpt0, rhs0) = tree
436
439
val rhs1 = context.unit.transformed.getOrElse(rhs0, rhs0)
437
- val body = if (noFieldNeeded ) rhs1
440
+ val body = if (noFieldHere ) rhs1
438
441
else gen.mkAssignAndReturn(basisSym, rhs1)
439
442
440
443
derivedSym setPos tree.pos // cannot set it at createAndEnterSymbol because basisSym can possibly still have NoPosition
@@ -465,7 +468,7 @@ trait MethodSynthesis {
465
468
override def keepClean = ! mods.isParamAccessor
466
469
467
470
override def derivedSym =
468
- if (noFieldNeeded ) NoSymbol
471
+ if (noFieldHere ) NoSymbol
469
472
else super .derivedSym
470
473
471
474
override def derivedTree = (
0 commit comments