@@ -145,15 +145,16 @@ sealed abstract class CaptureSet extends Showable:
145
145
146
146
/** x subsumes x
147
147
* this subsumes this.f
148
- * x subsumes y ==> x* subsumes y
149
- * x subsumes y ==> x* subsumes y*
148
+ * x subsumes y ==> x* subsumes y, x subsumes y?
149
+ * x subsumes y ==> x* subsumes y*, x? subsumes y?
150
150
*/
151
151
extension (x : CaptureRef )
152
152
private def subsumes (y : CaptureRef )(using Context ): Boolean =
153
153
(x eq y)
154
154
|| x.isRootCapability
155
155
|| y.match
156
- case y : TermRef => ! y.isReach && (y.prefix eq x)
156
+ case y : TermRef => y.prefix eq x
157
+ case MaybeCapability (y1) => x.stripMaybe.subsumes(y1)
157
158
case _ => false
158
159
|| x.match
159
160
case ReachCapability (x1) => x1.subsumes(y.stripReach)
@@ -312,6 +313,8 @@ sealed abstract class CaptureSet extends Showable:
312
313
def substParams (tl : BindingType , to : List [Type ])(using Context ) =
313
314
map(Substituters .SubstParamsMap (tl, to))
314
315
316
+ def maybe (using Context ): CaptureSet = map(MaybeMap ())
317
+
315
318
/** Invoke handler if this set has (or later aquires) the root capability `cap` */
316
319
def disallowRootCapability (handler : () => Context ?=> Unit )(using Context ): this .type =
317
320
if isUniversal then handler()
@@ -445,6 +448,8 @@ object CaptureSet:
445
448
def isConst = isSolved
446
449
def isAlwaysEmpty = false
447
450
451
+ def isMaybeSet = false // overridden in BiMapped
452
+
448
453
/** A handler to be invoked if the root reference `cap` is added to this set */
449
454
var rootAddedHandler : () => Context ?=> Unit = () => ()
450
455
@@ -490,9 +495,10 @@ object CaptureSet:
490
495
if elem.isRootCapability then
491
496
rootAddedHandler()
492
497
newElemAddedHandler(elem)
498
+ val normElem = if isMaybeSet then elem else elem.stripMaybe
493
499
// assert(id != 5 || elems.size != 3, this)
494
500
val res = (CompareResult .OK /: deps): (r, dep) =>
495
- r.andAlso(dep.tryInclude(elem , this ))
501
+ r.andAlso(dep.tryInclude(normElem , this ))
496
502
res.orElse:
497
503
elems -= elem
498
504
res.addToTrace(this )
@@ -508,6 +514,8 @@ object CaptureSet:
508
514
levelLimit.isContainedIn(elem.cls.levelOwner)
509
515
case ReachCapability (elem1) =>
510
516
levelOK(elem1)
517
+ case MaybeCapability (elem1) =>
518
+ levelOK(elem1)
511
519
case _ =>
512
520
true
513
521
@@ -760,6 +768,7 @@ object CaptureSet:
760
768
if source eq origin then supApprox.map(bimap.inverse)
761
769
else source.upperApprox(this ).map(bimap) ** supApprox
762
770
771
+ override def isMaybeSet : Boolean = bimap.isInstanceOf [MaybeMap ]
763
772
override def toString = s " BiMapped $id( $source, elems = $elems) "
764
773
end BiMapped
765
774
@@ -840,8 +849,7 @@ object CaptureSet:
840
849
upper.isAlwaysEmpty || upper.isConst && upper.elems.size == 1 && upper.elems.contains(r1)
841
850
if variance > 0 || isExact then upper
842
851
else if variance < 0 then CaptureSet .empty
843
- else if ctx.mode.is(Mode .Printing ) then upper
844
- else assert(false , i " trying to add $upper from $r via ${tm.getClass} in a non-variant setting " )
852
+ else upper.maybe
845
853
846
854
/** Apply `f` to each element in `xs`, and join result sets with `++` */
847
855
def mapRefs (xs : Refs , f : CaptureRef => CaptureSet )(using Context ): CaptureSet =
@@ -980,6 +988,26 @@ object CaptureSet:
980
988
/** The current VarState, as passed by the implicit context */
981
989
def varState (using state : VarState ): VarState = state
982
990
991
+ /** Maps `x` to `x?` */
992
+ private class MaybeMap (using Context ) extends BiTypeMap :
993
+
994
+ def apply (t : Type ) = t match
995
+ case t : CaptureRef if t.isTrackableRef => t.maybe
996
+ case _ => mapOver(t)
997
+
998
+ override def toString = " Maybe"
999
+
1000
+ lazy val inverse = new BiTypeMap :
1001
+
1002
+ def apply (t : Type ) = t match
1003
+ case t : CaptureRef if t.isMaybe => t.stripMaybe
1004
+ case t => mapOver(t)
1005
+
1006
+ def inverse = MaybeMap .this
1007
+
1008
+ override def toString = " Maybe.inverse"
1009
+ end MaybeMap
1010
+
983
1011
/* Not needed:
984
1012
def ofClass(cinfo: ClassInfo, argTypes: List[Type])(using Context): CaptureSet =
985
1013
CaptureSet.empty
0 commit comments