Skip to content

Commit b7f704d

Browse files
committed
Decouple constraints and cstates
1 parent 4d8927b commit b7f704d

9 files changed

+33
-40
lines changed

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

+3-5
Original file line numberDiff line numberDiff line change
@@ -74,11 +74,9 @@ class Run(comp: Compiler, ictx: Context) extends ImplicitRunInfo with Constraint
7474
.addMode(Mode.ImplicitsEnabled)
7575
.setTyperState(ctx.typerState.fresh(ctx.reporter))
7676
ctx.initialize()(using start) // re-initialize the base context with start
77-
atPeriod(ctx.period) {
78-
def addImport(ctx: Context, rootRef: ImportInfo.RootRef) =
79-
ctx.fresh.setImportInfo(ImportInfo.rootImport(rootRef))
80-
defn.RootImportFns.foldLeft(start.setRun(this))(addImport)
81-
}
77+
def addImport(ctx: Context, rootRef: ImportInfo.RootRef) =
78+
ctx.fresh.setImportInfo(ImportInfo.rootImport(rootRef))
79+
defn.RootImportFns.foldLeft(start.setRun(this))(addImport)
8280
}
8381

8482
private var compiling = false

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

+2-1
Original file line numberDiff line numberDiff line change
@@ -27,9 +27,10 @@ trait ConstraintHandling[AbstractContext] {
2727
def constr: config.Printers.Printer = config.Printers.constr
2828

2929
def comparerCtx(using AbstractContext): Context
30+
def comparerCState(using AbstractContext): CState
3031

3132
given (using AbstractContext) as Ctx = comparerCtx
32-
given (using AbstractContext) as CState = comparerCtx.cstate
33+
given (using AbstractContext) as CState = comparerCState
3334

3435
protected def isSubType(tp1: Type, tp2: Type)(implicit actx: AbstractContext): Boolean
3536
protected def isSameType(tp1: Type, tp2: Type)(implicit actx: AbstractContext): Boolean

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

+11-28
Original file line numberDiff line numberDiff line change
@@ -74,12 +74,12 @@ object Contexts {
7474

7575
/** Execute `op` at given period */
7676
inline def atPeriod[T](period: Period)(inline op: (Ctx, CState) ?=> T)(using Ctx, CState): T =
77-
op(using ctx.fresh.setPeriod(period), period)
77+
op(using ctx, period)
7878

7979
/** Execute `op` at given phase id */
8080
inline def atPhase[T](pid: PhaseId)(inline op: (Ctx, CState) ?=> T)(using Ctx, CState): T =
81-
op(using
82-
if pid == currentPhaseId then ctx else ctx.withPhase(pid),
81+
op(using ctx,
82+
// if pid == currentPhaseId then ctx else ctx.withPhase(pid),
8383
if pid == currentPhaseId then currentPeriod else Period(currentRunId, pid))
8484

8585
/** Execute `op` at given phase */
@@ -140,7 +140,7 @@ object Contexts {
140140
def importInfo: ImportInfo
141141
def gadt: GadtConstraint
142142
def searchHistory: SearchHistory
143-
def typeComparer: TypeComparer
143+
def typeComparer(using CState): TypeComparer
144144
def source: SourceFile
145145
def moreProperties: Map[Key[Any], Any]
146146
def property[T](key: Key[T]): Option[T]
@@ -178,6 +178,7 @@ object Contexts {
178178
def withPeriod(pd: Period): Context
179179
def withPhase(phaseId: PhaseId): Context
180180
def withPhase(phase: Phase): Context
181+
def withPhaseNoLater(phase: Phase): Context
181182
def withOwner(owner: Symbol): Ctx
182183
def withSource(source: SourceFile): Ctx
183184
def withProperty[T](key: Key[T], value: Option[T]): Ctx
@@ -321,9 +322,10 @@ object Contexts {
321322
*/
322323
private var _typeComparer: TypeComparer = _
323324
protected def typeComparer_=(typeComparer: TypeComparer): Unit = _typeComparer = typeComparer
324-
def typeComparer: TypeComparer = {
325+
def typeComparer(using CState): TypeComparer = {
325326
if (_typeComparer.comparerCtx ne this)
326327
_typeComparer = _typeComparer.copyIn(this)
328+
_typeComparer.initCState = currentPeriod
327329
_typeComparer
328330
}
329331

@@ -434,14 +436,6 @@ object Contexts {
434436
/** Sourcefile with given path, memoized */
435437
def getSource(path: String): SourceFile = getSource(path.toTermName)
436438

437-
/** Those fields are used to cache phases created in withPhase.
438-
* phasedCtx is first phase with altered phase ever requested.
439-
* phasedCtxs is array that uses phaseId's as indexes,
440-
* contexts are created only on request and cached in this array
441-
*/
442-
private var phasedCtx: Context = this
443-
private var phasedCtxs: Array[Context] = null
444-
445439
def withPeriod(pd: Period): Context =
446440
if period == pd then this else fresh.setPeriod(pd)
447441

@@ -450,17 +444,7 @@ object Contexts {
450444
*/
451445
final def withPhase(phaseId: PhaseId): Context =
452446
if (this.period.phaseId == phaseId) this
453-
else if (phasedCtx.period.phaseId == phaseId) phasedCtx
454-
else if (phasedCtxs != null && phasedCtxs(phaseId) != null) phasedCtxs(phaseId)
455-
else {
456-
val ctx1 = fresh.setPhase(phaseId)
457-
if (phasedCtx eq this) phasedCtx = ctx1
458-
else {
459-
if (phasedCtxs == null) phasedCtxs = new Array[Context](base.phases.length)
460-
phasedCtxs(phaseId) = ctx1
461-
}
462-
ctx1
463-
}
447+
else fresh.setPhase(phaseId)
464448

465449
final def withPhase(phase: Phase): Context =
466450
withPhase(phase.id)
@@ -554,11 +538,10 @@ object Contexts {
554538
this
555539
}
556540

557-
def reuseIn(outer: Context): this.type =
541+
def reuseIn(outer: Ctx)(using CState): this.type =
558542
implicitsCache = null
559-
phasedCtxs = null
560543
sourceCtx = null
561-
init(outer, outer)
544+
init(outer, outer, currentPeriod)
562545

563546
/** A fresh clone of this context embedded in this context. */
564547
def fresh: FreshContext = freshOver(this)
@@ -767,7 +750,7 @@ object Contexts {
767750
import base._
768751
val nestedCtx =
769752
if testsInUse < testContexts.size then
770-
testContexts(testsInUse).reuseIn(ctx.toContextUNSAFE)
753+
testContexts(testsInUse).reuseIn(ctx)
771754
else
772755
val ts = TyperState()
773756
.setReporter(TestingReporter())

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

+1
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,7 @@ final class ProperGadtConstraint private(
220220
// ---- Protected/internal -----------------------------------------------
221221

222222
override def comparerCtx(using ctx: Context): Context = ctx
223+
override def comparerCState(using ctx: Context): CState = ctx.cstate
223224

224225
override protected def constraint = myConstraint
225226
override protected def constraint_=(c: Constraint) = myConstraint = c

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

+1-1
Original file line numberDiff line numberDiff line change
@@ -1180,7 +1180,7 @@ object SymDenotations {
11801180
ctx.scope.lookup(name)
11811181
else
11821182
val outerCtx = ctx.outersIterator.dropWhile(_.scope eq ctx.scope).next()
1183-
companionNamed(name)(using outerCtx, outerCtx.toContextUNSAFE.cstate)
1183+
companionNamed(name)(using outerCtx)
11841184

11851185
/** Is this symbol the same or a linked class of `sym`? */
11861186
final def isLinkedWith(sym: Symbol)(using Ctx, CState): Boolean =

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

+4
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,11 @@ object AbsentContext {
3333
*/
3434
class TypeComparer(initctx: Context) extends ConstraintHandling[AbsentContext] with PatternTypeConstrainer {
3535
import TypeComparer._
36+
37+
var initCState: CState = _
38+
3639
def comparerCtx(using AbsentContext): Context = initctx
40+
def comparerCState(using AbsentContext): CState = initCState
3741

3842
val state = ctx.typerState
3943
def constraint: Constraint = state.constraint

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

+3-1
Original file line numberDiff line numberDiff line change
@@ -132,7 +132,9 @@ object TypeErasure {
132132

133133
/** The current context with a phase no later than erasure */
134134
inline def beforeErasure[T](inline op: (Ctx, CState) ?=> T)(using Ctx, CState) =
135-
atPhaseNoLater(erasurePhase)(op)
135+
atPhaseNoLater(erasurePhase) {
136+
op //(using ctx.withPhaseNoLater(erasurePhase))
137+
}
136138

137139
/** The standard erasure of a Scala type. Value classes are erased as normal classes.
138140
*

compiler/src/dotty/tools/dotc/transform/ElimErasedValueType.scala

+7-3
Original file line numberDiff line numberDiff line change
@@ -101,9 +101,13 @@ class ElimErasedValueType extends MiniPhase with InfoTransformer { thisPhase =>
101101
// super-accessors start as private, and their expanded name can clash after
102102
// erasure. TODO: Verify that this is OK.
103103
def bothSuperAccessors = sym1.name.is(SuperAccessorName) && sym2.name.is(SuperAccessorName)
104-
if (sym1.name != sym2.name && !bothSuperAccessors ||
105-
!info1.matchesLoosely(info2) && !bothPolyApply)
106-
report.error(DoubleDefinition(sym1, sym2, root), root.sourcePos)
104+
if (sym1.name != sym2.name && !bothSuperAccessors
105+
|| !info1.matchesLoosely(info2) && !bothPolyApply)
106+
then
107+
if false then
108+
println(i"diverge at $currentPhase $sym1: ${sym1.info}, $sym2: ${sym2.info}")
109+
report.error(DoubleDefinition(sym1, sym2, root), root.sourcePos)
110+
107111
}
108112
while (opc.hasNext) {
109113
val sym1 = opc.overriding

compiler/src/dotty/tools/dotc/typer/ImportInfo.scala

+1-1
Original file line numberDiff line numberDiff line change
@@ -184,7 +184,7 @@ class ImportInfo(symf: (Ctx, CState) ?=> Symbol,
184184
else
185185
var c = ctx.outer
186186
while c.importInfo eq ctx.importInfo do c = c.outer
187-
(c.importInfo != null) && c.importInfo.featureImported(feature, owner)(using c, c.toContextUNSAFE.cstate) // &&&: drop c.cstate, it's there to ensure period consistency
187+
(c.importInfo != null) && c.importInfo.featureImported(feature, owner)(using c)
188188

189189
if myOwner.ne(owner) || !myResults.contains(feature) then
190190
myOwner = owner

0 commit comments

Comments
 (0)