Skip to content

Commit af223d7

Browse files
committed
Add reach capabilities on the fly in getBoxed
1 parent 6930cec commit af223d7

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
@@ -320,18 +320,27 @@ extension (tp: Type)
320320
/** The capture set consisting of all top-level captures of `tp` that appear under a box.
321321
* Unlike for `boxed` this also considers parents of capture types, unions and
322322
* intersections, and type proxies other than abstract types.
323+
* Furthermore, if the original type is a capture ref `x`, it replaces boxed universal sets
324+
* on the fly with x*.
323325
*/
324326
def boxedCaptureSet(using Context): CaptureSet =
325-
def getBoxed(tp: Type): CaptureSet = tp match
327+
def getBoxed(tp: Type, pre: Type): CaptureSet = tp match
326328
case tp @ CapturingType(parent, refs) =>
327-
val pcs = getBoxed(parent)
328-
if tp.isBoxed then refs ++ pcs else pcs
329+
val pcs = getBoxed(parent, pre)
330+
if !tp.isBoxed then
331+
pcs
332+
else if pre.exists && refs.containsRootCapability then
333+
val reachRef = if refs.isReadOnly then pre.reach.readOnly else pre.reach
334+
pcs ++ reachRef.singletonCaptureSet
335+
else
336+
pcs ++ refs
337+
case ref: CaptureRef if ref.isTracked && !pre.exists => getBoxed(ref, ref)
329338
case tp: TypeRef if tp.symbol.isAbstractOrParamType => CaptureSet.empty
330-
case tp: TypeProxy => getBoxed(tp.superType)
331-
case tp: AndType => getBoxed(tp.tp1) ** getBoxed(tp.tp2)
332-
case tp: OrType => getBoxed(tp.tp1) ++ getBoxed(tp.tp2)
339+
case tp: TypeProxy => getBoxed(tp.superType, pre)
340+
case tp: AndType => getBoxed(tp.tp1, pre) ** getBoxed(tp.tp2, pre)
341+
case tp: OrType => getBoxed(tp.tp1, pre) ++ getBoxed(tp.tp2, pre)
333342
case _ => CaptureSet.empty
334-
getBoxed(tp)
343+
getBoxed(tp, NoType)
335344

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

0 commit comments

Comments
 (0)