Skip to content

Commit 59a890f

Browse files
committed
Move rule 1 logic to canDirectlyPromote
1 parent 51c73b9 commit 59a890f

File tree

1 file changed

+23
-13
lines changed

1 file changed

+23
-13
lines changed

compiler/src/dotty/tools/dotc/transform/init/Checking.scala

Lines changed: 23 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -254,34 +254,44 @@ object Checking {
254254
val Summary(pots, effs) = expand(pot)
255255
val effs2 = pots.map(FieldAccess(_, field)(eff.source))
256256
(effs2 ++ effs).toList.flatMap(check(_))
257-
258257
}
259258

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+
}
260277

261278
private def checkPromote(eff: Promote)(using state: State): Errors =
262279
if (state.safePromoted.contains(eff.potential)) Errors.empty
263280
else {
264281
val pot = eff.potential
265282
val errs = pot match {
283+
case pot if canDirectlyPromote(pot) =>
284+
Errors.empty
285+
266286
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
276287
PromoteThis(pot, eff.source, state.path).toErrors
277288

278289
case _: Cold =>
279290
PromoteCold(eff.source, state.path).toErrors
280291

281292
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
285295

286296
case Fun(pots, effs) =>
287297
val errs1 = state.test {

0 commit comments

Comments
 (0)