@@ -264,34 +264,44 @@ object Checking {
264
264
val Summary (pots, effs) = expand(pot)
265
265
val effs2 = pots.map(FieldAccess (_, field)(eff.source))
266
266
(effs2 ++ effs).toList.flatMap(check(_))
267
-
268
267
}
269
268
269
+ // / Check if we can just directly promote a potential.
270
+ // / A potential can be (currently) directly promoted if and only if:
271
+ // / - `pot == this` and all fields of this are initialized, or
272
+ // / - `pot == Warm(C, outer)` where `outer` can be directly promoted.
273
+ private def canDirectlyPromote (pot : Potential )(using state : State ): Boolean =
274
+ if (state.safePromoted.contains(pot)) true
275
+ else pot match {
276
+ case pot : ThisRef =>
277
+ // If we have all fields initialized, then we can promote This to hot.
278
+ val classRef = state.thisClass.info.asInstanceOf [ClassInfo ].appliedRef
279
+ classRef.fields.forall { denot =>
280
+ val sym = denot.symbol
281
+ sym.isOneOf(Flags .Lazy | Flags .Deferred ) || state.fieldsInited.contains(sym)
282
+ }
283
+ case Warm (cls, outer) =>
284
+ canDirectlyPromote(outer)
285
+ case _ => false
286
+ }
270
287
271
288
private def checkPromote (eff : Promote )(using state : State ): Errors =
272
289
if (state.safePromoted.contains(eff.potential)) Errors .empty
273
290
else {
274
291
val pot = eff.potential
275
292
val errs = pot match {
293
+ case pot if canDirectlyPromote(pot) =>
294
+ Errors .empty
295
+
276
296
case pot : ThisRef =>
277
- // If we have all fields initialized, then we can promote This to hot.
278
- val classRef = state.thisClass.info.asInstanceOf [ClassInfo ].appliedRef
279
- val allFieldsInited = classRef.fields.forall { denot =>
280
- val sym = denot.symbol
281
- sym.isOneOf(Flags .Lazy | Flags .Deferred ) || state.fieldsInited.contains(sym)
282
- }
283
- if (allFieldsInited)
284
- Errors .empty
285
- else
286
297
PromoteThis (pot, eff.source, state.path).toErrors
287
298
288
299
case _ : Cold =>
289
300
PromoteCold (eff.source, state.path).toErrors
290
301
291
302
case pot @ Warm (cls, outer) =>
292
- val errors = state.test { checkPromote(Promote (outer)(eff.source)) }
293
- if (errors.isEmpty) Errors .empty
294
- else PromoteWarm (pot, eff.source, state.path).toErrors
303
+ // TODO: Implement Rule 2
304
+ PromoteWarm (pot, eff.source, state.path).toErrors
295
305
296
306
case Fun (pots, effs) =>
297
307
val errs1 = state.test {
0 commit comments