Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

Commit 77c30e5

Browse files
authored
CC Language Reference Improvements v2 (#23818)
2 parents 17f1803 + 6e6cf79 commit 77c30e5

File tree

3 files changed

+113
-39
lines changed

3 files changed

+113
-39
lines changed

‎docs/_docs/reference/experimental/capture-checking/how-to-use.md‎

Lines changed: 42 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,48 @@ nightlyOf: https://docs.scala-lang.org/scala3/reference/experimental/capture-che
66

77
## Enabling Capture Checking
88

9-
TODO
9+
Use Scala 3 nightly for the latest features and fixes.
10+
11+
Add this import in any file that uses capture checking:
12+
```scala
13+
import language.experimental.captureChecking
14+
```
15+
16+
### Separation Checking
17+
18+
Requires the import above:
19+
```scala
20+
import language.experimental.captureChecking
21+
import language.experimental.separationChecking
22+
```
23+
24+
### SBT Project Template
25+
26+
Alternatively, you can clone a pre-defined SBT project to get
27+
started: https://github.com/lampepfl/scala3-cc-template
28+
29+
### The REPL/Scala-CLI
30+
31+
Using the command line through explicit parameters:
32+
```bash
33+
scala -S 3.nightly -language:experimental.captureChecking
34+
```
35+
or when reading from a file:
36+
```scala
37+
// foo.scala:
38+
//> using scala 3.nightly
39+
import language.experimental.captureChecking
40+
...
41+
```
42+
Then, it suffices to run
43+
```bash
44+
scala foo.scala
45+
```
46+
47+
## API Documentation
48+
49+
Scaladoc supports capture checking. The nightly standard library API docs have it enabled by default:
50+
https://nightly.scala-lang.org/api/
1051

1152
## Compilation Options
1253

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/classifiers-secondclass.scala:41:28 ----------------------
2+
41 | parReduce(1 to 1000): (a, b) => // error
3+
| ^
4+
|Found: (a: Int, b: Int) ->{f.write, f.read} Int
5+
|Required: (Int, Int) ->{cap.only[Read]} Int
6+
|
7+
|Note that capability f.write is not included in capture set {cap.only[Read]}.
8+
|
9+
|where: cap is a fresh root capability created in anonymous function of type (f2: Levels.File^): Unit when checking argument to parameter op of method parReduce
10+
42 | f.write(42) // the error stems from here
11+
43 | a + b + f.read() // ok
12+
|
13+
| longer explanation available when compiling with `-explain`
14+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/classifiers-secondclass.scala:53:30 ----------------------
15+
53 | parReduce(1 to 1000): (a, b) => // error
16+
| ^
17+
|Found: (a: Int, b: Int) ->{f.write, f.read, g.read} Int
18+
|Required: (Int, Int) ->{cap.only[Read]} Int
19+
|
20+
|Note that capability f.write is not included in capture set {cap.only[Read]}.
21+
|
22+
|where: cap is a fresh root capability created in anonymous function of type (g2: Levels.File^): Unit when checking argument to parameter op of method parReduce
23+
54 | f.write(42) // the error stems from here
24+
55 | a + b + f.read() + g.read() // ok
25+
|
26+
| longer explanation available when compiling with `-explain`
27+
-- [E007] Type Mismatch Error: tests/neg-custom-args/captures/classifiers-secondclass.scala:56:30 ----------------------
28+
56 | parReduce(1 to 1000): (a, b) => // error
29+
| ^
30+
|Found: (a: Int, b: Int) ->{g.write} Int
31+
|Required: (Int, Int) ->{cap.only[Read]} Int
32+
|
33+
|Note that capability g.write is not included in capture set {cap.only[Read]}.
34+
|
35+
|where: cap is a fresh root capability created in anonymous function of type (g2: Levels.File^): Unit when checking argument to parameter op of method parReduce
36+
57 | g.write(42) // the error stems from here
37+
58 | 0
38+
|
39+
| longer explanation available when compiling with `-explain`
Lines changed: 32 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -1,67 +1,61 @@
11
import language.experimental.captureChecking
22
import language.experimental.separationChecking
3+
import language.experimental.erasedDefinitions
4+
35
import caps.*
46

57
// Test inspired by the "Gentrification Gone too Far?" paper
68
object Levels:
79

10+
/* User-defined capability classifiers */
811
trait Read extends Classifier, SharedCapability
912
trait ReadWrite extends Classifier, SharedCapability
1013

1114
trait File(val name: String):
12-
val r: Read^
13-
val rw: ReadWrite^
14-
// operations guarded by boxed capability members
15+
// file-specific capability members, these are ensured to be erased
16+
erased val r: Read^
17+
erased val rw: ReadWrite^
18+
// operations guarded by capability members
1519
val read: () ->{r} Int
1620
val write: Int ->{rw} Unit
1721

1822
object File:
1923
def apply(s: String): File^ = new File(s) {
20-
val r = new Read {}
21-
val rw = new ReadWrite {}
24+
erased val r = new Read {}
25+
erased val rw = new ReadWrite {}
2226
val read = () =>
2327
println(s"Reading from $name with capability $r")
2428
42
2529
val write = (i: Int) =>
2630
println(s"Writing $i to $name with capability $rw")
2731
}
2832

29-
// Unfortunately, we do not have @use lambdas yet
30-
trait UseFunction[U]:
31-
def apply[C^](f: File^{C}): U
32-
33-
def withFile[U](name: String)(block: UseFunction[U]): U = block(File(name)) // unrestricted use of files & other capabilities
33+
def withFile[U](name: String)(block: File^ => U): U = block(File(name)) // unrestricted use of files & other capabilities
3434
def parReduce[U](xs: Seq[U])(op: (U, U) ->{cap.only[Read]} U): U = xs.reduce(op) // only Read-classified allowed
3535

3636
@main def test =
37-
withFile("foo.txt"):
38-
new UseFunction[Unit]:
39-
def apply[C^](f: File^{C}): Unit =
40-
f.read() // ok
41-
parReduce(1 to 1000): (a, b) =>
42-
a * b * f.read() // ok
43-
parReduce(1 to 1000): (a, b) => // error
44-
f.write(42) // the error stems from here
45-
a + b + f.read() // ok
46-
f.write(42) // ok, unrestricted access to file
37+
withFile("foo.txt"): f =>
38+
f.read() // ok
39+
parReduce(1 to 1000): (a, b) =>
40+
a * b * f.read() // ok
41+
parReduce(1 to 1000): (a, b) => // error
42+
f.write(42) // the error stems from here
43+
a + b + f.read() // ok
44+
f.write(42) // ok, unrestricted access to file
4745

4846
def testMulti =
49-
withFile("foo.txt"):
50-
new UseFunction[Unit]:
51-
def apply[C^](f: File^{C}): Unit =
52-
withFile("bar.txt"):
53-
new UseFunction[Unit]:
54-
def apply[C^](g: File^{C}): Unit =
55-
f.read() // ok
56-
g.read() // ok
57-
parReduce(1 to 1000): (a, b) =>
58-
a * b * f.read() + g.read() // ok
59-
parReduce(1 to 1000): (a, b) => // error
60-
f.write(42) // the error stems from here
61-
a + b + f.read() + g.read() // ok
62-
parReduce(1 to 1000): (a, b) => // error
63-
g.write(42) // the error stems from here
64-
0
65-
f.write(42) // ok, unrestricted access to file
66-
g.write(42) // ok, unrestricted access to file
47+
withFile("foo.txt"): f =>
48+
withFile("bar.txt"): g =>
49+
f.read() // ok
50+
g.read() // ok
51+
parReduce(1 to 1000): (a, b) =>
52+
a * b * f.read() + g.read() // ok
53+
parReduce(1 to 1000): (a, b) => // error
54+
f.write(42) // the error stems from here
55+
a + b + f.read() + g.read() // ok
56+
parReduce(1 to 1000): (a, b) => // error
57+
g.write(42) // the error stems from here
58+
0
59+
f.write(42) // ok, unrestricted access to file
60+
g.write(42) // ok, unrestricted access to file
6761

0 commit comments

Comments
(0)

AltStyle によって変換されたページ (->オリジナル) /