Skip to content

Commit bec52f3

Browse files
committed
Drop Periods and Phases mixins for contexts
Use `currentPhase`, `currentPeriod`, etc instead.
1 parent 625e29c commit bec52f3

39 files changed

+206
-216
lines changed

compiler/src/dotty/tools/dotc/Run.scala

+2-2
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
8585

8686
/** The context created for this run */
8787
given runContext[Dummy_so_its_a_def] as Context = myCtx
88-
assert(runContext.runId <= Periods.MaxPossibleRunId)
88+
assert(currentRunId(using runContext) <= Periods.MaxPossibleRunId)
8989

9090
private var myUnits: List[CompilationUnit] = _
9191
private var myUnitsCached: List[CompilationUnit] = _
@@ -236,7 +236,7 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
236236

237237
private def printTree(last: PrintedTree)(using Context): PrintedTree = {
238238
val unit = ctx.compilationUnit
239-
val prevPhase = ctx.phase.prev // can be a mini-phase
239+
val prevPhase = currentPhase.prev // can be a mini-phase
240240
val squashedPhase = ctx.base.squashed(prevPhase)
241241
val treeString = unit.tpdTree.show(using ctx.withProperty(XprintMode, Some(())))
242242

compiler/src/dotty/tools/dotc/ast/tpd.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -828,7 +828,7 @@ object tpd extends Trees.Instance[Type] with TypedTreeInfo {
828828
* owner by `from` to `to`.
829829
*/
830830
def changeOwnerAfter(from: Symbol, to: Symbol, trans: DenotTransformer)(using Context): ThisTree =
831-
if (ctx.phase == trans.next) {
831+
if (currentPhase == trans.next) {
832832
val traverser = new TreeTraverser {
833833
def traverse(tree: Tree)(using Context) = tree match {
834834
case tree: DefTree =>

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ object Annotations {
6868
case symFn: (Context => Symbol) @unchecked =>
6969
mySym = null
7070
mySym = symFn(annotCtx)
71-
case sym: Symbol if sym.defRunId != parentCtx.runId =>
71+
case sym: Symbol if sym.defRunId != currentRunId(using parentCtx) =>
7272
mySym = sym.denot.current.symbol
7373
case _ =>
7474
}

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

+19-12
Original file line numberDiff line numberDiff line change
@@ -70,10 +70,19 @@ object Contexts {
7070
atPhase(phase.id)(op)
7171

7272
inline def atNextPhase[T](inline op: Context ?=> T)(using Context): T =
73-
atPhase(ctx.phase.next)(op)
73+
atPhase(currentPhase.next)(op)
7474

7575
inline def atPhaseNotLaterThan[T](limit: Phase)(inline op: Context ?=> T)(using Context): T =
76-
op(using if !limit.exists || ctx.phase <= limit then ctx else ctx.withPhase(limit))
76+
op(using if !limit.exists || currentPhase <= limit then ctx else ctx.withPhase(limit))
77+
78+
inline def currentPeriod(using ctx: Context): Period = ctx.period
79+
80+
inline def currentPhase(using ctx: Context): Phase = ctx.base.phases(ctx.period.firstPhaseId)
81+
82+
inline def currentRunId(using ctx: Context): Int = ctx.period.runId
83+
84+
inline def currentPhaseId(using ctx: Context): Int = ctx.period.phaseId
85+
7786

7887
/** A context is passed basically everywhere in dotc.
7988
* This is convenient but carries the risk of captured contexts in
@@ -95,9 +104,7 @@ object Contexts {
95104
* classes (which should be short-lived).
96105
*/
97106
abstract class Context(val base: ContextBase)
98-
extends Periods
99-
with Phases
100-
with Printers
107+
extends Printers
101108
with Reporting { thiscontext =>
102109

103110
given Context = this
@@ -295,8 +302,8 @@ object Contexts {
295302
* This method will always return a phase period equal to phaseId, thus will never return squashed phases
296303
*/
297304
final def withPhase(phaseId: PhaseId): Context =
298-
if (this.phaseId == phaseId) this
299-
else if (phasedCtx.phaseId == phaseId) phasedCtx
305+
if (this.period.phaseId == phaseId) this
306+
else if (phasedCtx.period.phaseId == phaseId) phasedCtx
300307
else if (phasedCtxs != null && phasedCtxs(phaseId) != null) phasedCtxs(phaseId)
301308
else {
302309
val ctx1 = fresh.setPhase(phaseId)
@@ -312,10 +319,10 @@ object Contexts {
312319
withPhase(phase.id)
313320

314321
final def withPhaseNoLater(phase: Phase): Context =
315-
if (phase.exists && this.phase.id > phase.id) withPhase(phase) else this
322+
if (phase.exists && period.phaseId > phase.id) withPhase(phase) else this
316323

317324
final def withPhaseNoEarlier(phase: Phase): Context =
318-
if (phase.exists && this.phase.id < phase.id) withPhase(phase) else this
325+
if (phase.exists && period.phaseId < phase.id) withPhase(phase) else this
319326

320327
// `creationTrace`-related code. To enable, uncomment the code below and the
321328
// call to `setCreationTrace()` in this file.
@@ -439,7 +446,7 @@ object Contexts {
439446
}
440447

441448
/** Does current phase use an erased types interpretation? */
442-
def erasedTypes: Boolean = phase.erasedTypes
449+
def erasedTypes: Boolean = currentPhase(using this).erasedTypes
443450

444451
/** Is the debug option set? */
445452
def debug: Boolean = base.settings.Ydebug.value
@@ -602,8 +609,8 @@ object Contexts {
602609
def updateStore[T](loc: Store.Location[T], value: T): this.type =
603610
setStore(store.updated(loc, value))
604611

605-
def setPhase(pid: PhaseId): this.type = setPeriod(Period(runId, pid))
606-
def setPhase(phase: Phase): this.type = setPeriod(Period(runId, phase.start, phase.end))
612+
def setPhase(pid: PhaseId): this.type = setPeriod(Period(period.runId, pid))
613+
def setPhase(phase: Phase): this.type = setPeriod(Period(period.runId, phase.start, phase.end))
607614

608615
def setSetting[T](setting: Setting[T], value: T): this.type =
609616
setSettings(setting.updateIn(settingsState, value))

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

+5-5
Original file line numberDiff line numberDiff line change
@@ -867,7 +867,7 @@ class Definitions {
867867

868868
def ClassType(arg: Type)(using Context): Type = {
869869
val ctype = ClassClass.typeRef
870-
if (ctx.phase.erasedTypes) ctype else ctype.appliedTo(arg)
870+
if (currentPhase.erasedTypes) ctype else ctype.appliedTo(arg)
871871
}
872872

873873
/** The enumeration type, goven a value of the enumeration */
@@ -1041,13 +1041,13 @@ class Definitions {
10411041
name.drop(prefix.length).forall(_.isDigit))
10421042

10431043
def isBottomClass(cls: Symbol): Boolean =
1044-
if (ctx.explicitNulls && !ctx.phase.erasedTypes) cls == NothingClass
1044+
if (ctx.explicitNulls && !currentPhase.erasedTypes) cls == NothingClass
10451045
else isBottomClassAfterErasure(cls)
10461046

10471047
def isBottomClassAfterErasure(cls: Symbol): Boolean = cls == NothingClass || cls == NullClass
10481048

10491049
def isBottomType(tp: Type): Boolean =
1050-
if (ctx.explicitNulls && !ctx.phase.erasedTypes) tp.derivesFrom(NothingClass)
1050+
if (ctx.explicitNulls && !currentPhase.erasedTypes) tp.derivesFrom(NothingClass)
10511051
else isBottomTypeAfterErasure(tp)
10521052

10531053
def isBottomTypeAfterErasure(tp: Type): Boolean =
@@ -1357,9 +1357,9 @@ class Definitions {
13571357
private var current: RunId = NoRunId
13581358
private var cached: T = _
13591359
def apply()(using Context): T = {
1360-
if (current != ctx.runId) {
1360+
if (current != currentRunId) {
13611361
cached = generate(ctx)
1362-
current = ctx.runId
1362+
current = currentRunId
13631363
}
13641364
cached
13651365
}

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

+2-2
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ object DenotTransformers {
2424

2525
/** The validity period of the transformed denotations in the given context */
2626
def validFor(using Context): Period =
27-
Period(ctx.runId, id + 1, lastPhaseId)
27+
Period(currentRunId, id + 1, lastPhaseId)
2828

2929
/** The transformation method */
3030
def transform(ref: SingleDenotation)(using Context): SingleDenotation
@@ -43,7 +43,7 @@ object DenotTransformers {
4343
if (info1 eq ref.info) ref
4444
else ref match {
4545
case ref: SymDenotation =>
46-
ref.copySymDenotation(info = info1).copyCaches(ref, ctx.phase.next)
46+
ref.copySymDenotation(info = info1).copyCaches(ref, currentPhase.next)
4747
case _ =>
4848
ref.derivedSingleDenotation(ref.symbol, info1)
4949
}

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

+15-15
Original file line numberDiff line numberDiff line change
@@ -131,10 +131,10 @@ object Denotations {
131131
/** The denotation with info(s) as seen from prefix type */
132132
final def asSeenFrom(pre: Type)(using Context): AsSeenFromResult =
133133
if (Config.cacheAsSeenFrom) {
134-
if ((cachedPrefix ne pre) || ctx.period != validAsSeenFrom) {
134+
if ((cachedPrefix ne pre) || currentPeriod != validAsSeenFrom) {
135135
cachedAsSeenFrom = computeAsSeenFrom(pre)
136136
cachedPrefix = pre
137-
validAsSeenFrom = if (pre.isProvisional) Nowhere else ctx.period
137+
validAsSeenFrom = if (pre.isProvisional) Nowhere else currentPeriod
138138
}
139139
cachedAsSeenFrom
140140
}
@@ -686,14 +686,14 @@ object Denotations {
686686

687687
private def updateValidity()(using Context): this.type = {
688688
assert(
689-
ctx.runId >= validFor.runId
689+
currentRunId >= validFor.runId
690690
|| ctx.settings.YtestPickler.value // mixing test pickler with debug printing can travel back in time
691691
|| ctx.mode.is(Mode.Printing) // no use to be picky when printing error messages
692692
|| symbol.isOneOf(ValidForeverFlags),
693-
s"denotation $this invalid in run ${ctx.runId}. ValidFor: $validFor")
693+
s"denotation $this invalid in run ${currentRunId}. ValidFor: $validFor")
694694
var d: SingleDenotation = this
695695
while ({
696-
d.validFor = Period(ctx.period.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId)
696+
d.validFor = Period(currentPeriod.runId, d.validFor.firstPhaseId, d.validFor.lastPhaseId)
697697
d.invalidateInheritedInfo()
698698
d = d.nextInRun
699699
d ne this
@@ -720,7 +720,7 @@ object Denotations {
720720
case _ =>
721721
}
722722
if (!symbol.exists) return updateValidity()
723-
if (!coveredInterval.containsPhaseId(ctx.phaseId)) return NoDenotation
723+
if (!coveredInterval.containsPhaseId(currentPhaseId)) return NoDenotation
724724
if (ctx.debug) traceInvalid(this)
725725
staleSymbolError
726726
}
@@ -746,7 +746,7 @@ object Denotations {
746746
if (myValidFor.code <= 0) nextDefined else this
747747

748748
/** Produce a denotation that is valid for the given context.
749-
* Usually called when !(validFor contains ctx.period)
749+
* Usually called when !(validFor contains currentPeriod)
750750
* (even though this is not a precondition).
751751
* If the runId of the context is the same as runId of this denotation,
752752
* the right flock member is located, or, if it does not exist yet,
@@ -758,7 +758,7 @@ object Denotations {
758758
* the symbol is stale, which constitutes an internal error.
759759
*/
760760
def current(using Context): SingleDenotation = {
761-
val currentPeriod = ctx.period
761+
val currentPeriod = Contexts.currentPeriod
762762
val valid = myValidFor
763763
if (valid.code <= 0) {
764764
// can happen if we sit on a stale denotation which has been replaced
@@ -808,7 +808,7 @@ object Denotations {
808808
else {
809809
next match {
810810
case next: ClassDenotation =>
811-
assert(!next.is(Package), s"illegal transformation of package denotation by transformer ${ctx.withPhase(transformer).phase}")
811+
assert(!next.is(Package), s"illegal transformation of package denotation by transformer $transformer")
812812
case _ =>
813813
}
814814
next.insertAfter(cur)
@@ -842,7 +842,7 @@ object Denotations {
842842
}
843843

844844
private def demandOutsideDefinedMsg(using Context): String =
845-
s"demanding denotation of $this at phase ${ctx.phase}(${ctx.phaseId}) outside defined interval: defined periods are${definedPeriodsString}"
845+
s"demanding denotation of $this at phase ${currentPhase}(${currentPhaseId}) outside defined interval: defined periods are${definedPeriodsString}"
846846

847847
/** Install this denotation to be the result of the given denotation transformer.
848848
* This is the implementation of the same-named method in SymDenotations.
@@ -851,16 +851,16 @@ object Denotations {
851851
*/
852852
protected def installAfter(phase: DenotTransformer)(using Context): Unit = {
853853
val targetId = phase.next.id
854-
if (ctx.phaseId != targetId) atPhase(phase.next)(installAfter(phase))
854+
if (currentPhaseId != targetId) atPhase(phase.next)(installAfter(phase))
855855
else {
856856
val current = symbol.current
857857
// println(s"installing $this after $phase/${phase.id}, valid = ${current.validFor}")
858858
// printPeriods(current)
859-
this.validFor = Period(ctx.runId, targetId, current.validFor.lastPhaseId)
859+
this.validFor = Period(currentRunId, targetId, current.validFor.lastPhaseId)
860860
if (current.validFor.firstPhaseId >= targetId)
861861
current.replaceWith(this)
862862
else {
863-
current.validFor = Period(ctx.runId, current.validFor.firstPhaseId, targetId - 1)
863+
current.validFor = Period(currentRunId, current.validFor.firstPhaseId, targetId - 1)
864864
insertAfter(current)
865865
}
866866
}
@@ -919,7 +919,7 @@ object Denotations {
919919
case denot: SymDenotation => s"in ${denot.owner}"
920920
case _ => ""
921921
}
922-
s"stale symbol; $this#${symbol.id} $ownerMsg, defined in ${myValidFor}, is referred to in run ${ctx.period}"
922+
s"stale symbol; $this#${symbol.id} $ownerMsg, defined in ${myValidFor}, is referred to in run ${currentPeriod}"
923923
}
924924

925925
/** The period (interval of phases) for which there exists
@@ -1071,7 +1071,7 @@ object Denotations {
10711071
class ErrorDenotation(using Context) extends NonSymSingleDenotation(NoSymbol, NoType, NoType) {
10721072
override def exists: Boolean = false
10731073
override def hasUniqueSym: Boolean = false
1074-
validFor = Period.allInRun(ctx.runId)
1074+
validFor = Period.allInRun(currentRunId)
10751075
protected def newLikeThis(s: Symbol, i: Type, pre: Type): SingleDenotation =
10761076
this
10771077
}

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

+8-25
Original file line numberDiff line numberDiff line change
@@ -3,44 +3,27 @@ package dotty.tools.dotc.core
33
import Contexts._
44
import Phases.curPhases
55

6-
/** Periods are the central "clock" of the compiler
7-
* A period consists of a run id and a phase id.
8-
* run ids represent compiler runs
9-
* phase ids represent compiler phases
10-
*/
11-
abstract class Periods { thisCtx: Context =>
12-
import Periods._
13-
14-
/** The current phase identifier */
15-
def phaseId: Int = period.phaseId
16-
17-
/** The current run identifier */
18-
def runId: Int = period.runId
6+
object Periods {
197

208
/** The period containing the current period where denotations do not change.
219
* We compute this by taking as first phase the first phase less or equal to
2210
* the current phase that has the same "nextTransformerId". As last phase
2311
* we take the next transformer id following the current phase.
2412
*/
25-
def stablePeriod: Period = {
26-
var first = phaseId
27-
val nxTrans = thisCtx.base.nextDenotTransformerId(first)
28-
while (first - 1 > NoPhaseId && (thisCtx.base.nextDenotTransformerId(first - 1) == nxTrans))
13+
def currentStablePeriod(using Context): Period =
14+
var first = currentPhaseId
15+
val nxTrans = ctx.base.nextDenotTransformerId(first)
16+
while (first - 1 > NoPhaseId && (ctx.base.nextDenotTransformerId(first - 1) == nxTrans))
2917
first -= 1
30-
Period(runId, first, nxTrans)
31-
}
18+
Period(currentRunId, first, nxTrans)
3219

3320
/** Are all base types in the current period guaranteed to be the same as in period `p`? */
34-
def hasSameBaseTypesAs(p: Period): Boolean = {
35-
val period = thisCtx.period
21+
def currentHasSameBaseTypesAs(p: Period)(using Context): Boolean =
22+
val period = currentPeriod
3623
period == p ||
3724
period.runId == p.runId &&
3825
curPhases(period.phaseId).sameBaseTypesStartId ==
3926
curPhases(p.phaseId).sameBaseTypesStartId
40-
}
41-
}
42-
43-
object Periods {
4427

4528
/** A period is a contiguous sequence of phase ids in some run.
4629
* It is coded as follows:

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

+6-12
Original file line numberDiff line numberDiff line change
@@ -20,21 +20,15 @@ trait Phases {
2020
self: Context =>
2121

2222
import Phases._
23-
24-
def phase: Phase = base.phases(period.firstPhaseId)
25-
26-
def phasesStack: List[Phase] =
27-
if ((this eq NoContext) || !phase.exists) Nil
28-
else {
29-
val rest = outersIterator.dropWhile(_.phase == phase)
30-
phase :: (if (rest.hasNext) rest.next().phasesStack else Nil)
31-
}
32-
33-
def isAfterTyper: Boolean = base.isAfterTyper(phase)
3423
}
3524

3625
object Phases {
3726

27+
inline def phaseOf(id: PhaseId)(using Context): Phase =
28+
ctx.base.phases(id)
29+
30+
def currentlyAfterTyper(using Context): Boolean = ctx.base.isAfterTyper(currentPhase)
31+
3832
trait PhasesBase {
3933
this: ContextBase =>
4034

@@ -322,7 +316,7 @@ object Phases {
322316
/** Is this phase the standard typerphase? True for FrontEnd, but
323317
* not for other first phases (such as FromTasty). The predicate
324318
* is tested in some places that perform checks and corrections. It's
325-
* different from isAfterTyper (and cheaper to test).
319+
* different from currentlyAfterTyper (and cheaper to test).
326320
*/
327321
def isTyper: Boolean = false
328322

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -266,7 +266,7 @@ object Scopes {
266266

267267
/** enter a symbol in this scope. */
268268
final def enter[T <: Symbol](sym: T)(using Context): T = {
269-
if (sym.isType && ctx.phaseId <= typerPhase.id)
269+
if (sym.isType && currentPhaseId <= typerPhase.id)
270270
assert(lookup(sym.name) == NoSymbol,
271271
s"duplicate ${sym.debugString}; previous was ${lookup(sym.name).debugString}") // !!! DEBUG
272272
newScopeEntry(sym)

0 commit comments

Comments
 (0)