@@ -30,19 +30,30 @@ object Checking {
30
30
*
31
31
*/
32
32
case class State (
33
- visited : mutable. Set [Effect ], // effects that have been checked
33
+ private var visited : Set [Effect ], // effects that have been checked
34
34
path : Vector [Tree ], // the path that leads to the current effect
35
35
thisClass : ClassSymbol , // the concrete class of `this`
36
36
fieldsInited : mutable.Set [Symbol ],
37
37
parentsInited : mutable.Set [ClassSymbol ],
38
38
env : Env
39
39
) {
40
+
40
41
def withVisited (eff : Effect ): State = {
41
- visited += eff
42
+ visited = visited + eff
42
43
copy(path = this .path :+ eff.source)
43
44
}
44
45
46
+ def hasVisited (eff : Effect ): Boolean =
47
+ visited.contains(eff)
48
+
45
49
def withOwner (sym : Symbol ): State = copy(env = env.withOwner(sym))
50
+
51
+ def test (op : State ?=> Errors ): Errors = {
52
+ val saved = visited
53
+ val errors = op(using this )
54
+ visited = saved
55
+ errors
56
+ }
46
57
}
47
58
48
59
private implicit def theEnv (implicit state : State ): Env = state.env
@@ -148,7 +159,7 @@ object Checking {
148
159
}
149
160
150
161
private def check (eff : Effect )(implicit state : State ): Errors =
151
- if (state.visited.contains (eff)) Errors .empty
162
+ if (state.hasVisited (eff)) Errors .empty
152
163
else trace(" checking effect " + eff.show, init, errs => Errors .show(errs.asInstanceOf [Errors ])) {
153
164
implicit val state2 : State = state.withVisited(eff)
154
165
@@ -162,11 +173,13 @@ object Checking {
162
173
PromoteCold (eff.source, state2.path).toErrors
163
174
164
175
case pot @ Warm (cls, outer) =>
165
- PromoteWarm (pot, eff.source, state2.path).toErrors
176
+ val errors = state.test { check(Promote (outer)(eff.source)) }
177
+ if (errors.isEmpty) Errors .empty
178
+ else PromoteWarm (pot, eff.source, state2.path).toErrors
166
179
167
180
case Fun (pots, effs) =>
168
- val errs1 = effs.flatMap { check(_) }
169
- val errs2 = pots.flatMap { pot => check(Promote (pot)(eff.source))(state.copy(path = Vector .empty)) }
181
+ val errs1 = state.test { effs.flatMap { check(_) } }
182
+ val errs2 = state.test { pots.flatMap { pot => check(Promote (pot)(eff.source))(state.copy(path = Vector .empty)) } }
170
183
if (errs1.nonEmpty || errs2.nonEmpty)
171
184
UnsafePromotion (pot, eff.source, state2.path, errs1 ++ errs2).toErrors
172
185
else
0 commit comments