@@ -156,17 +156,24 @@ sealed abstract class CaptureSet extends Showable:
156156
157157 extension (x : CaptureRef )(using Context )
158158
159- /* x subsumes y if one of the following is true:
160- * - x is the same as y,
161- * - x is a this reference and y refers to a field of x
162- * - x is a super root of y
159+ /** x subsumes x
160+ * this subsumes this.f
161+ * x subsumes y ==> x* subsumes y
162+ * x subsumes y ==> x* subsumes y*
163163 */
164- private def subsumes (y : CaptureRef ) =
164+ private def subsumes (y : CaptureRef ): Boolean =
165165 (x eq y)
166166 || x.isSuperRootOf(y)
167167 || y.match
168- case y : TermRef => y. prefix eq x
168+ case y : TermRef => ! y.isReach && (y. prefix eq x)
169169 case _ => false
170+ || x.match
171+ case x : TermRef if x.isReach =>
172+ y.match
173+ case y : TermRef if y.isReach => x.reachPrefix.subsumes(y.reachPrefix)
174+ case _ => x.reachPrefix.subsumes(y)
175+ case _ =>
176+ false
170177
171178 /** x <:< cap, cap[x] <:< cap
172179 * cap[y] <:< cap[x] if y encloses x
@@ -530,7 +537,8 @@ object CaptureSet:
530537 if elem.isUniversalRootCapability then ! noUniversal
531538 else elem match
532539 case elem : TermRef =>
533- if levelLimit.exists then
540+ if elem.isReach then levelOK(elem.reachPrefix)
541+ else if levelLimit.exists then
534542 var sym = elem.symbol
535543 if sym.isLevelOwner then sym = sym.owner
536544 levelLimit.isContainedIn(sym.levelOwner)
@@ -1037,6 +1045,8 @@ object CaptureSet:
10371045 /** The capture set of the type underlying CaptureRef */
10381046 def ofInfo (ref : CaptureRef )(using Context ): CaptureSet = ref match
10391047 case ref : TermRef if ref.isRootCapability => ref.singletonCaptureSet
1048+ case ref : TermRef if ref.isReach => deepCaptureSet(ref.prefix.widen)
1049+ .showing(i " Deep capture set of $ref: ${ref.prefix.widen} = $result" , capt)
10401050 case _ => ofType(ref.underlying, followResult = true )
10411051
10421052 /** Capture set of a type */
@@ -1078,6 +1088,16 @@ object CaptureSet:
10781088 recur(tp)
10791089 .showing(i " capture set of $tp = $result" , captDebug)
10801090
1091+ private def deepCaptureSet (tp : Type )(using Context ): CaptureSet =
1092+ val collect = new TypeAccumulator [CaptureSet ]:
1093+ def apply (cs : CaptureSet , t : Type ) = t.dealias match
1094+ case t @ CapturingType (p, cs1) =>
1095+ val cs2 = apply(cs, p)
1096+ if variance > 0 then cs2 ++ cs1 else cs2
1097+ case _ =>
1098+ foldOver(cs, t)
1099+ collect(CaptureSet .empty, tp)
1100+
10811101 private val ShownVars : Property .Key [mutable.Set [Var ]] = Property .Key ()
10821102
10831103 /** Perform `op`. Under -Ycc-debug, collect and print info about all variables reachable
0 commit comments