Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion compiler/src/dotty/tools/dotc/cc/CaptureSet.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1644,7 +1644,8 @@ object CaptureSet:
else this(acc, parent)

def abstractTypeCase(acc: CaptureSet, t: TypeRef, upperBound: Type) =
if includeTypevars && upperBound.isExactlyAny then fresh(Origin.DeepCS(t))
if t.derivesFrom(defn.Caps_CapSet) then t.singletonCaptureSet
else if includeTypevars && upperBound.isExactlyAny then fresh(Origin.DeepCS(t))
else this(acc, upperBound)

collect(CaptureSet.empty, tp)
Expand Down
9 changes: 9 additions & 0 deletions tests/neg-custom-args/captures/i24309-region-orig.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
-- Error: tests/neg-custom-args/captures/i24309-region-orig.scala:17:36 ------------------------------------------------
17 | val x = r1.subregion[Ref^{r1.R}]: r2 => // error, limitation
| ^
| Local reach capability r1.R leaks into capture scope of enclosing function.
| You could try to abstract the capabilities referred to by r1.R in a capset variable.
18 | var a: Ref^{r1.R} = r1.alloc(0)
19 | var b: Ref^{r2.R} = r2.alloc(0)
20 | val c: Ref^{r1.R} = b
21 | a
22 changes: 22 additions & 0 deletions tests/neg-custom-args/captures/i24309-region-orig.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import language.experimental.captureChecking
import caps.*
class Ref(private var x: Int):
def get = x
def set(y: Int) = x = y
trait Region extends SharedCapability:
r: Region^ =>
type R^
def alloc(x: Int): Ref^{R} = Ref(x)
def subregion[T](f: (Region { type R >: r.R }) => T): T =
class R2 extends Region:
type R = r.R
f(new R2)
def withRegion[T](f: Region => T): T = f(new Region {})
@main def main() =
withRegion: r1 =>
val x = r1.subregion[Ref^{r1.R}]: r2 => // error, limitation
var a: Ref^{r1.R} = r1.alloc(0)
var b: Ref^{r2.R} = r2.alloc(0)
val c: Ref^{r1.R} = b
a
0
4 changes: 4 additions & 0 deletions tests/neg-custom-args/captures/i24309a.check
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
-- Error: tests/neg-custom-args/captures/i24309a.scala:4:34 ------------------------------------------------------------
4 |def runOps2[C^](): Unit = runOps[{C}](???) // error
| ^
| Capture set parameter C leaks into capture scope of method runOps2.
4 changes: 4 additions & 0 deletions tests/neg-custom-args/captures/i24309a.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
import language.experimental.captureChecking
def runOps[C^](ops: List[() ->{C} Unit]): Unit = ???
def runOps1[C^](xs: Object^{C}): Unit = runOps[{C}](???) // ok
def runOps2[C^](): Unit = runOps[{C}](???) // error
34 changes: 34 additions & 0 deletions tests/pos-custom-args/captures/i24309-region.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import language.experimental.captureChecking
import language.experimental.separationChecking

import caps.*

object Regions:
class Ref(private var x: Int):
def get = x
def set(y: Int) = x = y

trait Region[R^] extends SharedCapability:
region: Region[R]^ =>
def alloc(value: Int): Ref^{R} = Ref(value)

def subregion[T](f: [R2^ >: R] => (Region[R2]) => T): T =
val r = new Region[R] {}
f(r)


object Region:
def apply[T](f: [R^] => Region[R] => T): T =
val r = new Region[{}] {}
f(r)

@main def main() =
import Region.*
Region: [R^] =>
r1 =>
val x = r1.subregion: [R2^ >: R] =>
r2 =>
val a = r1.alloc(0)
val b = r2.alloc(0)
a
0
5 changes: 5 additions & 0 deletions tests/pos-custom-args/captures/i24309.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import language.experimental.captureChecking
trait Region[R^]
def id[T](x: T): T = ???
def foo[R^](r: Region[R]): Unit =
val t2 = () => id[Object^{R}](???) // was error, now ok
6 changes: 6 additions & 0 deletions tests/pos-custom-args/captures/i24309b.scala
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import language.experimental.captureChecking
def runOps[C^](ops: List[() ->{C} Unit]): Unit = ops.foreach(_()) // ok
trait Ops[C^] { def toList: List[() ->{C} Unit] }
def runOpsAlt1[C1^](ops: Ops[C1]): Unit = runOps[{C1}](???) // was error, now ok
def runOpsAlt2[C2^](ops: Ops[{}]^{C2}): Unit = runOps[{C2}](???) // ok
def runOpsAlt3[C3^](ops: Ops[C3]^{C3}): Unit = runOps[{C3}](???) // was error, no ok
Loading