@@ -1102,6 +1102,14 @@ object CaptureSet:
1102
1102
/** A map from captureset variables to their dependent sets at the time of the snapshot. */
1103
1103
private val depsMap : util.EqHashMap [Var , Deps ] = new util.EqHashMap
1104
1104
1105
+ /** A map from root.Result values to other such values. If two result values
1106
+ * `a` and `b` are unified, then `eqResultMap(a) = b` and `eqResultMap(b) = a`.
1107
+ */
1108
+ private var eqResultMap : util.SimpleIdentityMap [root.Result , root.Result ] = util.SimpleIdentityMap .empty
1109
+
1110
+ /** A snapshot of the `eqResultMap` value at the start of a VarState transaction */
1111
+ private var eqResultSnapshot : util.SimpleIdentityMap [root.Result , root.Result ] | Null = null
1112
+
1105
1113
/** The recorded elements of `v` (it's required that a recording was made) */
1106
1114
def elems (v : Var ): Refs = elemsMap(v)
1107
1115
@@ -1141,10 +1149,31 @@ object CaptureSet:
1141
1149
hidden.add(elem)(using ctx, this )
1142
1150
true
1143
1151
1152
+ /** If root1 and root2 belong to the same binder but have different originalBinders
1153
+ * it means that one of the roots was mapped to the binder of the other by a
1154
+ * substBinder when comparing two method types. In that case we can unify
1155
+ * the two roots1, provided none of the two roots have already been unified
1156
+ * themselves. So unification must be 1-1.
1157
+ */
1158
+ def unify (root1 : root.Result , root2 : root.Result )(using Context ): Boolean =
1159
+ (root1, root2) match
1160
+ case (root1 @ root.Result (binder1), root2 @ root.Result (binder2))
1161
+ if (binder1 eq binder2)
1162
+ && (root1.rootAnnot.originalBinder ne root2.rootAnnot.originalBinder)
1163
+ && eqResultMap(root1) == null
1164
+ && eqResultMap(root2) == null
1165
+ =>
1166
+ if eqResultSnapshot == null then eqResultSnapshot = eqResultMap
1167
+ eqResultMap = eqResultMap.updated(root1, root2).updated(root2, root1)
1168
+ true
1169
+ case _ =>
1170
+ false
1171
+
1144
1172
/** Roll back global state to what was recorded in this VarState */
1145
1173
def rollBack (): Unit =
1146
1174
elemsMap.keysIterator.foreach(_.resetElems()(using this ))
1147
1175
depsMap.keysIterator.foreach(_.resetDeps()(using this ))
1176
+ if eqResultSnapshot != null then eqResultMap = eqResultSnapshot.nn
1148
1177
1149
1178
private var seen : util.EqHashSet [CaptureRef ] = new util.EqHashSet
1150
1179
0 commit comments