@@ -35,7 +35,8 @@ sealed abstract class CaptureSet extends Showable:
35
35
*/
36
36
def elems : Refs
37
37
38
- /** Is this capture set constant (i.e. not a capture variable)?
38
+ /** Is this capture set constant (i.e. not an unsolved capture variable)?
39
+ * Solved capture variables count as constant.
39
40
*/
40
41
def isConst : Boolean
41
42
@@ -47,6 +48,11 @@ sealed abstract class CaptureSet extends Showable:
47
48
/** Is this capture set definitely non-empty? */
48
49
final def isNotEmpty : Boolean = ! elems.isEmpty
49
50
51
+ /** Cast to variable. @pre: @isConst */
52
+ def asVar : Var =
53
+ assert(! isConst)
54
+ asInstanceOf [Var ]
55
+
50
56
/** Add new elements to this capture set if allowed.
51
57
* @pre `newElems` is not empty and does not overlap with `this.elems`.
52
58
* Constant capture sets never allow to add new elements.
@@ -133,24 +139,22 @@ sealed abstract class CaptureSet extends Showable:
133
139
def ** (that : CaptureSet )(using Context ): CaptureSet =
134
140
if this .subCaptures(that, frozen = true ) == CompareResult .OK then this
135
141
else if that.subCaptures(this , frozen = true ) == CompareResult .OK then that
136
- else (this , that) match
137
- case (cs1 : Const , cs2 : Const ) => Const (cs1.elems.intersect(cs2.elems))
138
- case (cs1 : Var , cs2) => Intersected (cs1, cs2)
139
- case (cs1, cs2 : Var ) => Intersected (cs2, cs1)
142
+ else if this .isConst && that.isConst then Const (elems.intersect(that.elems))
143
+ else if that.isConst then Intersected (this .asVar, that)
144
+ else Intersected (that.asVar, this )
140
145
141
146
def -- (that : CaptureSet .Const )(using Context ): CaptureSet =
142
147
val elems1 = elems.filter(! that.accountsFor(_))
143
148
if elems1.size == elems.size then this
144
- else this match
145
- case cs1 : Const => Const (elems1)
146
- case cs1 : Var => Diff (cs1, that)
149
+ else if this .isConst then Const (elems1)
150
+ else Diff (asVar, that)
147
151
148
152
def - (ref : CaptureRef )(using Context ): CaptureSet =
149
153
this -- ref.singletonCaptureSet
150
154
151
- def filter (p : CaptureRef => Boolean )(using Context ): CaptureSet = this match
152
- case cs1 : Const => Const (elems.filter(p))
153
- case cs1 : Var => Filtered (cs1 , p)
155
+ def filter (p : CaptureRef => Boolean )(using Context ): CaptureSet =
156
+ if this .isConst then Const (elems.filter(p))
157
+ else Filtered (asVar , p)
154
158
155
159
/** capture set obtained by applying `f` to all elements of the current capture set
156
160
* and joining the results. If the current capture set is a variable, the same
@@ -159,14 +163,12 @@ sealed abstract class CaptureSet extends Showable:
159
163
def map (tm : TypeMap )(using Context ): CaptureSet = tm match
160
164
case tm : BiTypeMap =>
161
165
val mappedElems = elems.map(tm.forward)
162
- this match
163
- case cs : Const => Const (mappedElems)
164
- case cs : Var => BiMapped (cs, tm, mappedElems)
166
+ if isConst then Const (mappedElems)
167
+ else BiMapped (asVar, tm, mappedElems)
165
168
case _ =>
166
169
val mapped = mapRefs(elems, tm, tm.variance)
167
- this match
168
- case cs : Const => mapped
169
- case cs : Var => Mapped (cs, tm, tm.variance, mapped)
170
+ if isConst then mapped
171
+ else Mapped (asVar, tm, tm.variance, mapped)
170
172
171
173
def substParams (tl : BindingType , to : List [Type ])(using Context ) =
172
174
map(Substituters .SubstParamsMap (tl, to))
@@ -227,9 +229,11 @@ object CaptureSet:
227
229
varId += 1
228
230
varId
229
231
232
+ private var isSolved : Boolean = false
233
+
230
234
var elems : Refs = initialElems
231
235
var deps : Deps = emptySet
232
- def isConst = false
236
+ def isConst = isSolved
233
237
def isAlwaysEmpty = false
234
238
235
239
private def recordElemsState ()(using VarState ): Boolean =
@@ -249,7 +253,7 @@ object CaptureSet:
249
253
deps = state.deps(this )
250
254
251
255
def addNewElems (newElems : Refs , origin : CaptureSet )(using Context , VarState ): CompareResult =
252
- if recordElemsState() then
256
+ if ! isConst && recordElemsState() then
253
257
elems ++= newElems
254
258
// assert(id != 2 || elems.size != 2, this)
255
259
val depsIt = deps.iterator
@@ -298,12 +302,10 @@ object CaptureSet:
298
302
Const (newElems)
299
303
val result = super .addNewElems(added.elems, origin)
300
304
if result == CompareResult .OK then
301
- added match
302
- case added : Var =>
303
- if added.recordDepsState() then addSub(added)
304
- else CompareResult .fail(this )
305
- case _ =>
306
- result
305
+ if added.isConst then result
306
+ else if added.asVar.recordDepsState() then { addSub(added); result }
307
+ else CompareResult .fail(this )
308
+ else result
307
309
308
310
override def toString = s " Mapped $id( $cv, elems = $elems) "
309
311
end Mapped
@@ -367,8 +369,10 @@ object CaptureSet:
367
369
val OK : Type = Const (emptySet)
368
370
def fail (cs : CaptureSet ): Type = cs
369
371
extension (result : Type )
372
+ def isOK : Boolean = result eq OK
370
373
def blocking : CaptureSet = result
371
374
def show : String = if result == OK then " OK" else result.toString
375
+ inline def andAlso (op : => Type ) = if result.isOK then op else result
372
376
373
377
class VarState :
374
378
private val elemsMap : util.EqHashMap [Var , Refs ] = new util.EqHashMap
0 commit comments