@@ -30,19 +30,30 @@ object Checking {
3030 *
3131 */
3232 case class State (
33- visited : mutable. Set [Effect ], // effects that have been checked
33+ private var visited : Set [Effect ], // effects that have been checked
3434 path : Vector [Tree ], // the path that leads to the current effect
3535 thisClass : ClassSymbol , // the concrete class of `this`
3636 fieldsInited : mutable.Set [Symbol ],
3737 parentsInited : mutable.Set [ClassSymbol ],
3838 env : Env
3939 ) {
40+
4041 def withVisited (eff : Effect ): State = {
41- visited += eff
42+ visited = visited + eff
4243 copy(path = this .path :+ eff.source)
4344 }
4445
46+ def hasVisited (eff : Effect ): Boolean =
47+ visited.contains(eff)
48+
4549 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+ }
4657 }
4758
4859 private implicit def theEnv (implicit state : State ): Env = state.env
@@ -148,7 +159,7 @@ object Checking {
148159 }
149160
150161 private def check (eff : Effect )(implicit state : State ): Errors =
151- if (state.visited.contains (eff)) Errors .empty
162+ if (state.hasVisited (eff)) Errors .empty
152163 else trace(" checking effect " + eff.show, init, errs => Errors .show(errs.asInstanceOf [Errors ])) {
153164 implicit val state2 : State = state.withVisited(eff)
154165
@@ -162,11 +173,13 @@ object Checking {
162173 PromoteCold (eff.source, state2.path).toErrors
163174
164175 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
166179
167180 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)) } }
170183 if (errs1.nonEmpty || errs2.nonEmpty)
171184 UnsafePromotion (pot, eff.source, state2.path, errs1 ++ errs2).toErrors
172185 else
0 commit comments