Skip to content

Commit b7f4d72

Browse files
committed
Fix exemption logic for consuming paths
* Do not include root capabilities when computing consumed paths. * Adjust exemption check to consider both capability and its reach, except for root capabilities.
1 parent 633d548 commit b7f4d72

File tree

1 file changed

+18
-4
lines changed

1 file changed

+18
-4
lines changed

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

Lines changed: 18 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -600,11 +600,18 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
600600
// Check if this class has any consume fields
601601
val hasConsumeFields = cls.info.decls.exists(m => m.isConsumeParam && m.isTerm)
602602
if hasConsumeFields then
603+
// Use the capture set of the widened type
604+
val captureSet = ref.widen.captureSet.elems
603605
// Use the capture set of the reference itself (e.g., {a} for holder.a : A^{a})
604606
// Return both the capabilities in the capture set AND what they transitively consume
605-
var result = ref.widen.captureSet.elems
606-
for cap <- ref.widen.captureSet.elems do
607-
result = result ++ consumedByPath(cap)
607+
var result = emptyRefs
608+
for cap <- captureSet do
609+
// Stop at cap - don't include fresh root capabilities
610+
cap match
611+
case _: RootCapability => // Skip
612+
case _ =>
613+
result = result + cap
614+
result = result ++ consumedByPath(cap)
608615
result
609616
else
610617
emptyRefs
@@ -659,7 +666,14 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
659666
val pathConsumed = consumedByPath(ref)
660667

661668
// Check if any capability consumed by the path was consumed at position `pos`.
662-
val shouldExempt = pathConsumed.exists(consumed.get(_) == pos)
669+
// We need to check both the capability and its reach, since consumed might store the reach version.
670+
val shouldExempt = pathConsumed.exists { cap =>
671+
if consumed.get(cap) == pos then
672+
true
673+
else cap match
674+
case _: RootCapability => false // RootCapability.reach is unsupported
675+
case _ => consumed.get(cap.reach) == pos
676+
}
663677

664678
if !shouldExempt then
665679
consumeError(ref, pos, tree.srcPos)

0 commit comments

Comments
 (0)