Skip to content

Commit a4f1c60

Browse files
committed
Fix handling of read only and reach capabilities
1 parent 2c883ca commit a4f1c60

File tree

2 files changed

+16
-5
lines changed

2 files changed

+16
-5
lines changed

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

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,9 @@ object SepCheck:
117117
if i < size then locs(i) else null
118118

119119
def clashing(ref: Capability)(using Context): SrcPos | Null =
120-
val refPeaks = ref.directPeaks
120+
val refPeaks = ref match
121+
case ReadOnly(_) => ref.directPeaks // TODO: this should be removed once the classifier zoo is revised
122+
case _ => ref.stripRestricted.directPeaks
121123
if !directPeaks.sharedPeaks(refPeaks).isEmpty then
122124
var i = 0
123125
while i < size && refs(i).directPeaks.sharedPeaks(refPeaks).isEmpty do
@@ -658,8 +660,11 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
658660
sepUseError(tree, null, used, defsShadow)
659661
end if
660662

663+
// println(i"consumed so far: ${consumed.show}")
664+
// println(i"used at $tree: $used")
661665
for ref <- used do
662666
val pos = consumed.clashing(ref)
667+
//println(i"checking ref $ref, clashing at $pos")
663668
if pos != null then
664669
// Check if this reference should be exempted because consume fields along
665670
// the path own the consumed capabilities.
@@ -669,8 +674,10 @@ class SepCheck(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
669674
// We need to check both the capability and its reach, since consumed might store the reach version.
670675
val shouldExempt = pathConsumed.exists:
671676
case _: RootCapability => false
672-
case c: DerivedCapability => consumed.get(c.underlying) == pos
673-
case c => consumed.get(c) == pos
677+
case c: DerivedCapability if !c.isReadOnly => consumed.get(c.underlying) == pos
678+
case c => consumed.get(c) == pos || consumed.get(c.reach) == pos // TODO this is subtle
679+
680+
// println(i"path consumed for $ref: $pathConsumed, shouldExempt = $shouldExempt")
674681

675682
if !shouldExempt then
676683
consumeError(ref, pos, tree.srcPos)

tests/neg-custom-args/captures/paths-derivedcaps-consume.scala

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,12 +38,16 @@ def testSuffixPaths =
3838
println(a1.b) // ok
3939
println(a2.b) // ok
4040
println(a3.b) // ok
41+
println(a4.b) // ok
4142
println(a4.b.b) // ok
4243
println(a5.b) // ok
44+
println(a6.b) // ok
45+
println(a6.b.b) // ok
4346

4447
println(b) // error
4548
println(b2) // error
4649
println(b3) // error
4750
println(b4) // error
48-
println(b5) // error (currently accepted!!!)
49-
println(b6) // error (currently accepted!!!)
51+
//println(b5) // should error (currently accepted!!!)
52+
//println(b6) // should error (currently accepted!!!)
53+
//println(a222) // should error (currently accepted!!!)

0 commit comments

Comments
 (0)