Skip to content

Commit 68b711c

Browse files
committed
Maintain TyperState invariants after mergeConstraints
1 parent eff4cb1 commit 68b711c

File tree

1 file changed

+16
-6
lines changed

1 file changed

+16
-6
lines changed

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

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -120,19 +120,29 @@ class TyperState() {
120120
if constraint ne targetState.constraint then
121121
Stats.record("typerState.commit.new constraint")
122122
constr.println(i"committing $this to $targetState, fromConstr = $constraint, toConstr = ${targetState.constraint}")
123-
if targetState.constraint eq previousConstraint then targetState.constraint = constraint
124-
else targetState.mergeConstraintWith(this)
125-
if !ownedVars.isEmpty then
126-
for tvar <- ownedVars do
127-
tvar.owningState = new WeakReference(targetState)
128-
targetState.ownedVars ++= ownedVars
123+
if targetState.constraint eq previousConstraint then
124+
targetState.constraint = constraint
125+
if !ownedVars.isEmpty then ownedVars.foreach(targetState.includeVar)
126+
else
127+
targetState.mergeConstraintWith(this)
129128
targetState.gc()
130129
reporter.flush()
131130
isCommitted = true
132131
}
133132

134133
def mergeConstraintWith(that: TyperState)(using Context): Unit =
135134
constraint = constraint & (that.constraint, otherHasErrors = that.reporter.errorsReported)
135+
for tvar <- constraint.uninstVars do
136+
if !isOwnedAnywhere(this, tvar) then ownedVars += tvar
137+
for tl <- constraint.domainLambdas do
138+
if constraint.isRemovable(tl) then constraint = constraint.remove(tl)
139+
140+
private def includeVar(tvar: TypeVar)(using Context): Unit =
141+
tvar.owningState = new WeakReference(this)
142+
ownedVars += tvar
143+
144+
private def isOwnedAnywhere(ts: TyperState, tvar: TypeVar): Boolean =
145+
ts.ownedVars.contains(tvar) || ts.previous != null && isOwnedAnywhere(ts.previous, tvar)
136146

137147
/** Make type variable instances permanent by assigning to `inst` field if
138148
* type variable instantiation cannot be retracted anymore. Then, remove

0 commit comments

Comments
 (0)