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