Skip to content

Commit 5a9e830

Browse files
committed
Add reach capabilities on the fly in getBoxed
1 parent abecb04 commit 5a9e830

File tree

1 file changed

+16
-7
lines changed

1 file changed

+16
-7
lines changed

compiler/src/dotty/tools/dotc/cc/CaptureOps.scala

Lines changed: 16 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -332,18 +332,27 @@ extension (tp: Type)
332332
/** The capture set consisting of all top-level captures of `tp` that appear under a box.
333333
* Unlike for `boxed` this also considers parents of capture types, unions and
334334
* intersections, and type proxies other than abstract types.
335+
* Furthermore, if the original type is a capture ref `x`, it replaces boxed universal sets
336+
* on the fly with x*.
335337
*/
336338
def boxedCaptureSet(using Context): CaptureSet =
337-
def getBoxed(tp: Type): CaptureSet = tp match
339+
def getBoxed(tp: Type, pre: Type): CaptureSet = tp match
338340
case tp @ CapturingType(parent, refs) =>
339-
val pcs = getBoxed(parent)
340-
if tp.isBoxed then refs ++ pcs else pcs
341+
val pcs = getBoxed(parent, pre)
342+
if !tp.isBoxed then
343+
pcs
344+
else if pre.exists && refs.containsRootCapability then
345+
val reachRef = if refs.isReadOnly then pre.reach.readOnly else pre.reach
346+
pcs ++ reachRef.singletonCaptureSet
347+
else
348+
pcs ++ refs
349+
case ref: CaptureRef if ref.isTracked && !pre.exists => getBoxed(ref, ref)
341350
case tp: TypeRef if tp.symbol.isAbstractOrParamType => CaptureSet.empty
342-
case tp: TypeProxy => getBoxed(tp.superType)
343-
case tp: AndType => getBoxed(tp.tp1) ** getBoxed(tp.tp2)
344-
case tp: OrType => getBoxed(tp.tp1) ++ getBoxed(tp.tp2)
351+
case tp: TypeProxy => getBoxed(tp.superType, pre)
352+
case tp: AndType => getBoxed(tp.tp1, pre) ** getBoxed(tp.tp2, pre)
353+
case tp: OrType => getBoxed(tp.tp1, pre) ++ getBoxed(tp.tp2, pre)
345354
case _ => CaptureSet.empty
346-
getBoxed(tp)
355+
getBoxed(tp, NoType)
347356

348357
/** Is the boxedCaptureSet of this type nonempty? */
349358
def isBoxedCapturing(using Context): Boolean =

0 commit comments

Comments
 (0)