Skip to content

Commit a3f3ae3

Browse files
authored
Optimize and harden isCaptureChecking tests (#24439)
- Base it only on ids, no phase dereferencing needed - Make sure checkCapturesPhaseId is not confused with current id even if checkCapturesPhase does not exist and current phase is not set.
2 parents 25401d0 + 1c3ad97 commit a3f3ae3

File tree

2 files changed

+16
-11
lines changed

2 files changed

+16
-11
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

Lines changed: 7 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -22,20 +22,16 @@ private val Captures: Key[CaptureSet] = Key()
2222

2323
/** Are we at checkCaptures phase? */
2424
def isCaptureChecking(using Context): Boolean =
25-
ctx.phaseId == Phases.checkCapturesPhase.id
25+
ctx.phaseId == Phases.checkCapturesPhaseId
2626

2727
/** Are we in the CheckCaptures or Setup phase? */
2828
def isCaptureCheckingOrSetup(using Context): Boolean =
29-
val ccPhase = Phases.checkCapturesPhase
30-
ccPhase.exists
31-
&& {
32-
val ccId = ccPhase.id
33-
val ctxId = ctx.phaseId
34-
ctxId == ccId
35-
|| ctxId == ccId - 1 && ccState.iterationId > 0
36-
// Note: just checking phase id is not enough since Setup would
37-
// also be the phase after pattern matcher.
38-
}
29+
val ccId = Phases.checkCapturesPhaseId
30+
val ctxId = ctx.phaseId
31+
ctxId == ccId
32+
|| ctxId == ccId - 1 && ccState.iterationId > 0
33+
// Note: just checking phase id is not enough since Setup would
34+
// also be the phase after pattern matcher.
3935

4036
/** A dependent function type with given arguments and result type
4137
* TODO Move somewhere else where we treat all function type related ops together.

compiler/src/dotty/tools/dotc/core/Phases.scala

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -216,6 +216,9 @@ object Phases {
216216
else
217217
this.fusedPhases = this.phases
218218

219+
if myCheckCapturesPhase.exists then
220+
myCheckCapturesPhaseId = myCheckCapturesPhase.id
221+
219222
config.println(s"Phases = ${phases.toList}")
220223
config.println(s"nextDenotTransformerId = ${nextDenotTransformerId.toList}")
221224
}
@@ -257,6 +260,10 @@ object Phases {
257260
private var myGenBCodePhase: Phase = uninitialized
258261
private var myCheckCapturesPhase: Phase = uninitialized
259262

263+
private var myCheckCapturesPhaseId: Int = -2
264+
// -1 means undefined, 0 means NoPhase, we make sure that we don't get a false hit
265+
// if ctx.phaseId is either of these.
266+
260267
final def parserPhase: Phase = myParserPhase
261268
final def typerPhase: Phase = myTyperPhase
262269
final def postTyperPhase: Phase = myPostTyperPhase
@@ -285,6 +292,7 @@ object Phases {
285292
final def flattenPhase: Phase = myFlattenPhase
286293
final def genBCodePhase: Phase = myGenBCodePhase
287294
final def checkCapturesPhase: Phase = myCheckCapturesPhase
295+
final def checkCapturesPhaseId: Int = myCheckCapturesPhaseId
288296

289297
private def setSpecificPhases() = {
290298
def phaseOfClass(pclass: Class[?]) = phases.find(pclass.isInstance).getOrElse(NoPhase)
@@ -570,6 +578,7 @@ object Phases {
570578
def flattenPhase(using Context): Phase = ctx.base.flattenPhase
571579
def genBCodePhase(using Context): Phase = ctx.base.genBCodePhase
572580
def checkCapturesPhase(using Context): Phase = ctx.base.checkCapturesPhase
581+
def checkCapturesPhaseId(using Context): Int = ctx.base.checkCapturesPhaseId
573582

574583
def unfusedPhases(using Context): Array[Phase] = ctx.base.phases
575584

0 commit comments

Comments
 (0)