@@ -2,16 +2,27 @@ package dotty.tools
2
2
package dotc
3
3
package core
4
4
5
- import util .*
6
5
import Types .* , Symbols .* , Flags .* , Contexts .* , Decorators .*
7
6
import config .Printers .capt
8
7
import annotation .threadUnsafe
9
8
import annotation .internal .sharable
10
9
import reporting .trace
11
10
import printing .{Showable , Printer }
12
11
import printing .Texts .*
12
+ import util .SimpleIdentitySet
13
+ import util .common .alwaysTrue
13
14
14
15
/** A class for capture sets. Capture sets can be constants or variables.
16
+ * Capture sets support inclusion constraints <:< where <:< is subcapturing.
17
+ * They also allow mapping with arbitrary functions from elements to capture sets,
18
+ * by supporting a monadic flatMap operation. That is, constraints can be
19
+ * of one of the following forms
20
+ *
21
+ * cs1 <:< cs2
22
+ * cs1 = ∪ {f(x) | x ∈ cs2}
23
+ *
24
+ * where the `f`s are arbitrary functions from capture references to capture sets.
25
+ * We call the resulting constraint system "monadic set constraints".
15
26
*/
16
27
sealed abstract class CaptureSet extends Showable :
17
28
import CaptureSet .*
@@ -148,7 +159,7 @@ object CaptureSet:
148
159
override def toString = elems.toString
149
160
end Const
150
161
151
- class Var private [CaptureSet ] (initialElems : Refs ) extends CaptureSet :
162
+ class Var private [CaptureSet ] (initialElems : Refs , validate : Refs => Boolean = alwaysTrue ) extends CaptureSet :
152
163
val id =
153
164
varId += 1
154
165
varId
@@ -158,6 +169,8 @@ object CaptureSet:
158
169
def isConst = false
159
170
def isEmpty = false
160
171
172
+ assert(validate(elems))
173
+
161
174
private def recordState ()(using VarState ) = varState.get(this ) match
162
175
case None => varState(this ) = elems
163
176
case _ =>
@@ -166,7 +179,8 @@ object CaptureSet:
166
179
elems = state(this )
167
180
168
181
def addNewElems (newElems : Refs )(using Context , VarState ): Boolean =
169
- deps.forall(_.tryInclude(newElems))
182
+ validate(newElems)
183
+ && deps.forall(_.tryInclude(newElems))
170
184
&& {
171
185
recordState()
172
186
elems ++= newElems
@@ -190,13 +204,13 @@ object CaptureSet:
190
204
override def toString = s " Mapped $id$elems"
191
205
end Mapped
192
206
207
+ def mapRefs (xs : Refs , f : CaptureRef => CaptureSet )(using Context ): CaptureSet =
208
+ (empty /: xs)((cs, x) => cs ++ f(x))
209
+
193
210
type VarState = util.EqHashMap [Var , Refs ]
194
211
195
212
def varState (using state : VarState ): VarState = state
196
213
197
- def mapRefs (xs : Refs , f : CaptureRef => CaptureSet )(using Context ): CaptureSet =
198
- (empty /: xs)((cs, x) => cs ++ f(x))
199
-
200
214
def ofClass (cinfo : ClassInfo , argTypes : List [Type ])(using Context ): CaptureSet =
201
215
def captureSetOf (tp : Type ): CaptureSet = tp match
202
216
case tp : TypeRef if tp.symbol.is(ParamAccessor ) =>
0 commit comments