@@ -16,9 +16,16 @@ import NameKinds.TraitSetterName
16
16
import NameOps ._
17
17
import Flags ._
18
18
import Decorators ._
19
+ import StdNames .nme
20
+
21
+ import util .Store
19
22
20
23
object Memoize {
21
24
val name : String = " memoize"
25
+
26
+ private final class MyState {
27
+ val classesThatNeedReleaseFence = new util.HashSet [Symbol ]
28
+ }
22
29
}
23
30
24
31
/** Provides the implementations of all getters and setters, introducing
@@ -37,10 +44,17 @@ object Memoize {
37
44
* --> <accessor> <mods> def x_=(y: T): Unit = x = y
38
45
*/
39
46
class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
47
+ import Memoize .MyState
40
48
import ast .tpd ._
41
49
42
50
override def phaseName : String = Memoize .name
43
51
52
+ private var MyState : Store .Location [MyState ] = _
53
+ private def myState (using Context ): MyState = ctx.store(MyState )
54
+
55
+ override def initContext (ctx : FreshContext ): Unit =
56
+ MyState = ctx.addLocation[MyState ]()
57
+
44
58
/* Makes sure that, after getters and constructors gen, there doesn't
45
59
* exist non-deferred definitions that are not implemented. */
46
60
override def checkPostCondition (tree : Tree )(using Context ): Unit = {
@@ -69,6 +83,17 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
69
83
*/
70
84
override def runsAfter : Set [String ] = Set (Mixin .name)
71
85
86
+ override def prepareForUnit (tree : Tree )(using Context ): Context =
87
+ ctx.fresh.updateStore(MyState , new MyState ())
88
+
89
+ override def transformTemplate (tree : Template )(using Context ): Tree =
90
+ val cls = ctx.owner.asClass
91
+ if myState.classesThatNeedReleaseFence.contains(cls) then
92
+ val releaseFenceCall = ref(defn.staticsMethodRef(nme.releaseFence)).appliedToNone
93
+ cpy.Template (tree)(tree.constr, tree.parents, Nil , tree.self, tree.body :+ releaseFenceCall)
94
+ else
95
+ tree
96
+
72
97
override def transformDefDef (tree : DefDef )(using Context ): Tree = {
73
98
val sym = tree.symbol
74
99
@@ -154,7 +179,11 @@ class Memoize extends MiniPhase with IdentityDenotTransformer { thisPhase =>
154
179
// See tests/run/traitValOverriddenByParamAccessor.scala
155
180
tree
156
181
else
157
- field.setFlag(Mutable ) // Necessary for vals mixed in from traits
182
+ if ! field.is(Mutable ) then
183
+ // This is a val mixed in from a trait.
184
+ // We make it mutable, and mark the class as needing a releaseFence() in the constructor
185
+ field.setFlag(Mutable )
186
+ myState.classesThatNeedReleaseFence += sym.owner
158
187
val initializer =
159
188
if (isErasableBottomField(field, tree.vparamss.head.head.tpt.tpe.classSymbol)) Literal (Constant (()))
160
189
else Assign (ref(field), adaptToField(field, ref(tree.vparamss.head.head.symbol)))
0 commit comments