@@ -61,10 +61,6 @@ sealed abstract class CaptureSet extends Showable:
61
61
*/
62
62
def levelLimit : Symbol
63
63
64
- def rootSet (using Context ): CaptureSet =
65
- assert(levelLimit.exists, this )
66
- levelLimit.localRoot.termRef.singletonCaptureSet
67
-
68
64
/** Is this capture set definitely non-empty? */
69
65
final def isNotEmpty : Boolean = ! elems.isEmpty
70
66
@@ -144,16 +140,30 @@ sealed abstract class CaptureSet extends Showable:
144
140
extension (x : CaptureRef )(using Context )
145
141
private def subsumes (y : CaptureRef ) =
146
142
(x eq y)
143
+ || x.isSuperRootOf(y)
147
144
|| y.match
148
- case y : TermRef => (y.prefix eq x) || y.isLocalRootCapability && x.isSuperRootOf(y)
149
- case y : CaptureRoot .Var => x.isSuperRootOf(y)
145
+ case y : TermRef => y.prefix eq x
150
146
case _ => false
151
147
|| (x.isGenericRootCapability || y.isRootCapability && x.isRootCapability)
152
148
&& ctx.property(LooseRootChecking ).isDefined
153
149
154
- private def isSuperRootOf (y : CaptureRoot ) = x match
155
- case x : CaptureRoot =>
156
- x.isGenericRootCapability || x.isLocalRootCapability && y.encloses(x)
150
+ /** x <:< cap, cap[x] <:< cap
151
+ * cap[y] <:< cap[x] if y encloses x
152
+ * y <:< cap[x] if y's level owner encloses x's local root owner
153
+ */
154
+ private def isSuperRootOf (y : CaptureRef ): Boolean = x match
155
+ case x : TermRef =>
156
+ if x.isGenericRootCapability then true
157
+ else if x.isLocalRootCapability && ! y.isGenericRootCapability then
158
+ val xowner = x.localRootOwner
159
+ y match
160
+ case y : TermRef =>
161
+ xowner.isContainedIn(y.symbol.levelOwner)
162
+ case y : ThisType =>
163
+ xowner.isContainedIn(y.cls)
164
+ case _ =>
165
+ false
166
+ else false
157
167
case _ => false
158
168
end extension
159
169
@@ -207,9 +217,10 @@ sealed abstract class CaptureSet extends Showable:
207
217
def recur (elems : List [CaptureRef ]): CompareResult = elems match
208
218
case elem :: elems1 =>
209
219
var result = that.tryInclude(elem, this )
210
- if ! result.isOK && ! elem.isRootCapability && summon[ VarState ] != FrozenState then
220
+ if ! result.isOK then
211
221
ccState.levelError = ccState.levelError.orElse(result.levelError)
212
- result = result.orElse(elem.captureSetOfInfo.subCaptures(that))
222
+ if ! elem.isRootCapability && summon[VarState ] != FrozenState then
223
+ result = result.orElse(elem.captureSetOfInfo.subCaptures(that))
213
224
if result.isOK then
214
225
recur(elems1)
215
226
else
@@ -322,22 +333,6 @@ sealed abstract class CaptureSet extends Showable:
322
333
def substParams (tl : BindingType , to : List [Type ])(using Context ) =
323
334
map(Substituters .SubstParamsMap (tl, to))
324
335
325
- /** The capture root that corresponds to this capture set. This is:
326
- * - if the capture set is a Var with a defined level limit, the
327
- * associated capture root,
328
- * - otherwise, if the set is nonempty, the innermost root such
329
- * that some element of the set subcaptures this root,
330
- * - otherwise, if the set is empty, `default`.
331
- */
332
- def impliedRoot (default : CaptureRoot )(using Context ): CaptureRoot =
333
- if levelLimit.exists then levelLimit.localRoot.termRef
334
- else if elems.isEmpty then default
335
- else elems.toList
336
- .map:
337
- case elem : CaptureRoot if elem.isLocalRootCapability => elem
338
- case elem => elem.captureSetOfInfo.impliedRoot(default)
339
- .reduce((x : CaptureRoot , y : CaptureRoot ) => CaptureRoot .lub(x, y))
340
-
341
336
/** Invoke handler if this set has (or later aquires) the root capability `cap` */
342
337
def disallowRootCapability (handler : () => Context ?=> Unit )(using Context ): this .type =
343
338
if isUniversal then handler()
@@ -459,7 +454,7 @@ object CaptureSet:
459
454
varId += 1
460
455
varId
461
456
462
- // assert(id != 95 )
457
+ // assert(id != 40 )
463
458
464
459
override val levelLimit =
465
460
if directOwner.exists then directOwner.levelOwner else NoSymbol
@@ -525,12 +520,15 @@ object CaptureSet:
525
520
if elem.isGenericRootCapability then rootAddedHandler()
526
521
newElemAddedHandler(elem)
527
522
// assert(id != 5 || elems.size != 3, this)
528
- (CompareResult .OK /: deps) { (r, dep) =>
523
+ val res = (CompareResult .OK /: deps) { (r, dep) =>
529
524
r.andAlso(dep.tryInclude(elem, this ))
530
525
}.addToTrace(this )
526
+ if ! res.isOK then elems -= elem
527
+ res
531
528
532
529
private def levelOK (elem : CaptureRef )(using Context ): Boolean =
533
- ! levelLimit.exists
530
+ if elem.isGenericRootCapability then ! noUniversal
531
+ else ! levelLimit.exists
534
532
|| elem.match
535
533
case elem : TermRef =>
536
534
var sym = elem.symbol
@@ -571,15 +569,15 @@ object CaptureSet:
571
569
else if elems.exists(_.isRootCapability) then
572
570
CaptureSet (elems.filter(_.isRootCapability).toList* )
573
571
else if computingApprox then
574
- rootSet
572
+ universal
575
573
else
576
574
computingApprox = true
577
575
try computeApprox(origin).ensuring(_.isConst)
578
576
finally computingApprox = false
579
577
580
578
/** The intersection of all upper approximations of dependent sets */
581
579
protected def computeApprox (origin : CaptureSet )(using Context ): CaptureSet =
582
- (rootSet /: deps) { (acc, sup) => acc ** sup.upperApprox(this ) }
580
+ (universal /: deps) { (acc, sup) => acc ** sup.upperApprox(this ) }
583
581
584
582
/** Widen the variable's elements to its upper approximation and
585
583
* mark it as constant from now on. This is used for contra-variant type variables
@@ -720,7 +718,7 @@ object CaptureSet:
720
718
if source eq origin then
721
719
// it's a mapping of origin, so not a superset of `origin`,
722
720
// therefore don't contribute to the intersection.
723
- rootSet
721
+ universal
724
722
else
725
723
source.upperApprox(this ).map(tm)
726
724
@@ -788,7 +786,7 @@ object CaptureSet:
788
786
if source eq origin then
789
787
// it's a filter of origin, so not a superset of `origin`,
790
788
// therefore don't contribute to the intersection.
791
- rootSet
789
+ universal
792
790
else
793
791
source.upperApprox(this ).filter(p)
794
792
@@ -819,7 +817,7 @@ object CaptureSet:
819
817
if (origin eq cs1) || (origin eq cs2) then
820
818
// it's a combination of origin with some other set, so not a superset of `origin`,
821
819
// therefore don't contribute to the intersection.
822
- rootSet
820
+ universal
823
821
else
824
822
CaptureSet (elemIntersection(cs1.upperApprox(this ), cs2.upperApprox(this )))
825
823
@@ -1010,10 +1008,6 @@ object CaptureSet:
1010
1008
def ofInfo (ref : CaptureRef )(using Context ): CaptureSet = ref match
1011
1009
case ref : TermRef if ref.isRootCapability =>
1012
1010
ref.singletonCaptureSet
1013
- case ref : TermRef if ref.symbol.isLevelOwner =>
1014
- ofType(ref.underlying, followResult = true ).filter(
1015
- ref.symbol.localRoot.termRef != _)
1016
- // TODO: Can replace filter with - ref.symbol.localRoot.termRef when we drop level nesting
1017
1011
case _ =>
1018
1012
ofType(ref.underlying, followResult = true )
1019
1013
@@ -1095,12 +1089,18 @@ object CaptureSet:
1095
1089
override def toAdd (using Context ) =
1096
1090
for CompareResult .LevelError (cs, ref) <- ccState.levelError.toList yield
1097
1091
ccState.levelError = None
1098
- val levelStr = ref match
1099
- case ref : TermRef => i " , defined in ${ref.symbol.maybeOwner}"
1100
- case _ => " "
1101
- i """
1102
- |
1103
- |Note that reference ${ref}$levelStr
1104
- |cannot be included in outer capture set $cs which is associated with ${cs.levelLimit}"""
1092
+ if ref.isGenericRootCapability then
1093
+ i """
1094
+ |
1095
+ |Note that the universal capability `cap`
1096
+ |cannot be included in capture set $cs"""
1097
+ else
1098
+ val levelStr = ref match
1099
+ case ref : TermRef => i " , defined in ${ref.symbol.maybeOwner}"
1100
+ case _ => " "
1101
+ i """
1102
+ |
1103
+ |Note that reference ${ref}$levelStr
1104
+ |cannot be included in outer capture set $cs which is associated with ${cs.levelLimit}"""
1105
1105
1106
1106
end CaptureSet
0 commit comments