Skip to content

Commit

Permalink
Switch version where separation checking starts to 3.8
Browse files Browse the repository at this point in the history
3.7 is already on us, so bump by one.

Two new tests for separation checking. One i15749a required a change in SepCheck:
We need to be able to declare reach capabilities in dependencies. The reach is
imply dropped. But we can't sometimes use a normal capability since its capture
set might be empty.
  • Loading branch information
odersky committed Jan 21, 2025
1 parent b114ada commit 0b9acb3
Show file tree
Hide file tree
Showing 17 changed files with 44 additions and 26 deletions.
2 changes: 1 addition & 1 deletion compiler/src/dotty/tools/dotc/cc/SepCheck.scala
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,7 @@ class SepChecker(checker: CheckCaptures.CheckerAPI) extends tpd.TreeTraverser:
(formal, arg) <- mt.paramInfos.zip(args)
dep <- formal.captureSet.elems.toList
do
val referred = dep match
val referred = dep.stripReach match
case dep: TermParamRef =>
argMap(dep.binder)(dep.paramNum) :: Nil
case dep: ThisType if dep.cls == fn.symbol.owner =>
Expand Down
2 changes: 1 addition & 1 deletion project/Build.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1223,7 +1223,7 @@ object Build {
settings(scala2LibraryBootstrappedSettings).
settings(
moduleName := "scala2-library-cc",
scalacOptions ++= Seq("-Ycheck:all", "-source", "3.7")
scalacOptions ++= Seq("-Ycheck:all", "-source", "3.8")
)

lazy val scala2LibraryBootstrappedSettings = Seq(
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/box-adapt-cases.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on
trait Cap { def use(): Int }

def test1(): Unit = {
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/depfun-reach.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import language.experimental.captureChecking
import caps.cap
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on
def test(io: Object^, async: Object^) =
def compose(op: List[(() ->{cap} Unit, () ->{cap} Unit)]): List[() ->{op*} Unit] =
List(() => op.foreach((f,g) => { f(); g() }))
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/existential-mapping.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import language.experimental.captureChecking
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on
class A
class C
type Fun[X] = (x: C^) -> X
Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/i19330.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on
import language.experimental.captureChecking


Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/i21614.scala
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import language.experimental.captureChecking
import caps.Capability
import caps.use
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on
trait List[+T]:
def map[U](f: T => U): List[U]

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/lazyref.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on
class CC
type Cap = CC^

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/outer-var.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on
class CC
type Cap = CC^

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/reaches.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import caps.use; import language.`3.7` // sepchecks on
import caps.use; import language.`3.8` // sepchecks on
class File:
def write(): Unit = ???

Expand Down
35 changes: 25 additions & 10 deletions tests/neg-custom-args/captures/reaches2.check
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
-- Error: tests/neg-custom-args/captures/reaches2.scala:8:10 -----------------------------------------------------------
8 | ps.map((x, y) => compose1(x, y)) // error // error
| ^
|reference ps* is not included in the allowed capture set {}
|of an enclosing function literal with expected type ((box A ->{ps*} A, box A ->{ps*} A)) -> box (x$0: A^?) ->? A^?
-- Error: tests/neg-custom-args/captures/reaches2.scala:8:13 -----------------------------------------------------------
8 | ps.map((x, y) => compose1(x, y)) // error // error
| ^
|reference ps* is not included in the allowed capture set {}
|of an enclosing function literal with expected type ((box A ->{ps*} A, box A ->{ps*} A)) -> box (x$0: A^?) ->? A^?
-- Error: tests/neg-custom-args/captures/reaches2.scala:10:10 ----------------------------------------------------------
10 | ps.map((x, y) => compose1(x, y)) // error // error // error
| ^
|reference ps* is not included in the allowed capture set {}
|of an enclosing function literal with expected type ((box A ->{ps*} A, box A ->{ps*} A)) -> box (x$0: A^?) ->? A^?
-- Error: tests/neg-custom-args/captures/reaches2.scala:10:13 ----------------------------------------------------------
10 | ps.map((x, y) => compose1(x, y)) // error // error // error
| ^
|reference ps* is not included in the allowed capture set {}
|of an enclosing function literal with expected type ((box A ->{ps*} A, box A ->{ps*} A)) -> box (x$0: A^?) ->? A^?
-- Error: tests/neg-custom-args/captures/reaches2.scala:10:31 ----------------------------------------------------------
10 | ps.map((x, y) => compose1(x, y)) // error // error // error
| ^
| Separation failure: argument of type (x$0: A) ->{y} box A^?
| to method compose1: [A, B, C](f: A => B, g: B => C): A ->{f, g} C
| corresponds to capture-polymorphic formal parameter g of type box A^? => box A^?
| and captures {ps*}, but this capability is also passed separately
| in the first argument with type (x$0: A) ->{x} box A^?.
|
| Capture set of first argument : {x}
| Hidden set of current argument : {y}
| Footprint of first argument : {x, ps*}
| Hidden footprint of current argument : {y, ps*}
| Declared footprint of current argument: {}
| Undeclared overlap of footprints : {ps*}
4 changes: 3 additions & 1 deletion tests/neg-custom-args/captures/reaches2.scala
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
import language.`3.8` // sepchecks on

class List[+A]:
def map[B](f: A -> B): List[B] = ???

def compose1[A, B, C](f: A => B, g: B => C): A ->{f, g} C =
z => g(f(z))

def mapCompose[A](ps: List[(A => A, A => A)]): List[A ->{ps*} A] =
ps.map((x, y) => compose1(x, y)) // error // error
ps.map((x, y) => compose1(x, y)) // error // error // error

2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/unsound-reach-2.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import language.experimental.captureChecking; import language.`3.7` // sepchecks on
import language.experimental.captureChecking; import language.`3.8` // sepchecks on
trait Consumer[-T]:
def apply(x: T): Unit

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/unsound-reach-3.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


import language.experimental.captureChecking; import language.`3.7` // sepchecks on
import language.experimental.captureChecking; import language.`3.8` // sepchecks on
trait File:
def close(): Unit

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/unsound-reach-4.scala
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@


import language.experimental.captureChecking; import language.`3.7` // sepchecks on
import language.experimental.captureChecking; import language.`3.8` // sepchecks on
trait File:
def close(): Unit

Expand Down
2 changes: 1 addition & 1 deletion tests/neg-custom-args/captures/vars.scala
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import language.`3.7` // sepchecks on
import language.`3.8` // sepchecks on

class CC
type Cap = CC^
Expand Down
3 changes: 2 additions & 1 deletion tests/pos-custom-args/captures/i15749a.scala
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import caps.cap
import caps.use
import language.`3.8` // sepchecks on

class Unit
object u extends Unit
Expand All @@ -13,7 +14,7 @@ def test =
def wrapper[T](x: T): Wrapper[T] = Wrapper:
[X] => (op: T ->{cap} X) => op(x)

def strictMap[A <: Top, B <: Top](mx: Wrapper[A])(f: A ->{cap} B): Wrapper[B] =
def strictMap[A <: Top, B <: Top](mx: Wrapper[A])(f: A ->{cap, mx*} B): Wrapper[B] =
mx.value((x: A) => wrapper(f(x)))

def force[A](thunk: Unit ->{cap} A): A = thunk(u)
Expand Down

0 comments on commit 0b9acb3

Please sign in to comment.