@@ -23,14 +23,19 @@ object TyperState {
2323 .setReporter(new ConsoleReporter ())
2424 .setCommittable(true )
2525
26- opaque type Snapshot = (Constraint , TypeVars )
26+ opaque type Snapshot = (Constraint , TypeVars , TypeVars )
2727
2828 extension (ts : TyperState )
29- def snapshot (): Snapshot = (ts.constraint, ts.ownedVars)
29+ def snapshot ()(using Context ): Snapshot =
30+ var previouslyInstantiated : TypeVars = SimpleIdentitySet .empty
31+ for tv <- ts.ownedVars do if tv.inst.exists then previouslyInstantiated += tv
32+ (ts.constraint, ts.ownedVars, previouslyInstantiated)
3033
3134 def resetTo (state : Snapshot )(using Context ): Unit =
32- val (c, tvs) = state
33- for tv <- tvs do if tv.isInstantiated then tv.resetInst(ts)
35+ val (c, tvs, previouslyInstantiated) = state
36+ for tv <- tvs do
37+ if tv.inst.exists && ! previouslyInstantiated.contains(tv) then
38+ tv.resetInst(ts)
3439 ts.ownedVars = tvs
3540 ts.constraint = c
3641}
@@ -74,7 +79,11 @@ class TyperState() {
7479
7580 private var isCommitted : Boolean = _
7681
77- /** The set of uninstantiated type variables which have this state as their owning state */
82+ /** The set of uninstantiated type variables which have this state as their owning state
83+ * NOTE: It could be that a variable in `ownedVars` is already instantiated. This is because
84+ * the link between ownedVars and variable instantiation in TypeVar#setInst is made up
85+ * from a weak reference and weak references can have spurious nulls.
86+ */
7887 private var myOwnedVars : TypeVars = _
7988 def ownedVars : TypeVars = myOwnedVars
8089 def ownedVars_= (vs : TypeVars ): Unit = myOwnedVars = vs
@@ -187,7 +196,7 @@ class TyperState() {
187196 Stats .record(" typerState.gc" )
188197 val toCollect = new mutable.ListBuffer [TypeLambda ]
189198 for tvar <- ownedVars do
190- if ! tvar.inst.exists then
199+ if ! tvar.inst.exists then // See comment of `ownedVars` for why this test is necessary
191200 val inst = constraint.instType(tvar)
192201 if inst.exists then
193202 tvar.setInst(inst)
0 commit comments