Skip to content

Commit b898c49

Browse files
committed
Expand on this capture sets and inheritance
1 parent 47c5fa3 commit b898c49

File tree

2 files changed

+36
-3
lines changed

2 files changed

+36
-3
lines changed

docs/_docs/contributing/scaladoc.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ In case of any discrepancies rely on the source files instead.
8484
the names of directories containing corresponding TASTY files
8585
and the kinds of signatures from source files (corresponding to keywords used to declare them like `def`, `class`, `object` etc.)
8686
whose presence in the generated documentation will be checked (other signatures, when missing, will be ignored).
87-
The mentioned source files should be located directly inside [](../scaladoc-testcases/src/tests) directory
87+
The mentioned source files should be located directly inside the [scaladoc-testcases](https://github.com/scala/scala3/tree/main/scaladoc-testcases) directory
8888
but the file names passed as parameters should contain neither this path prefix nor `.scala` suffix.
8989

9090
By default it's expected that all signatures from the source files will be present in the documentation

docs/_docs/reference/experimental/capture-checking/classes.md

Lines changed: 35 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -77,9 +77,10 @@ we know that the type of `this` must be pure, since `this` is the right hand sid
7777

7878
### Traits and Open Classes
7979

80-
The self-type inference behaves differently depending on whether all subclasses of a class are known. For a regular (non-open, non-abstract) class, all subclasses are known at compile time, so the capture checker can precisely infer the self-type. However, for traits, abstract classes, and [`open`](../other-new-features/open-classes.md) classes, arbitrary subclasses may exist, so the capture checker conservatively assumes that `this` may capture capabilities.
80+
The self-type inference behaves differently depending on whether all subclasses of a class are known. For a regular (non-open, non-abstract) class, all subclasses are known at compile time, so the capture checker can precisely infer the self-type. However, for traits, abstract classes, and [`open`](../../other-new-features/open-classes.md) classes, arbitrary subclasses may exist, so the capture checker conservatively assumes that `this` may capture arbitrary capabilities
81+
(i.e., it infers the universal capture set `cap`).
8182

82-
For example:
83+
For example (assuming all definitions are in the same file):
8384
```scala
8485
class A:
8586
def fn: A = this // ok
@@ -102,6 +103,38 @@ open class E:
102103
def fn2: E^ = this // ok
103104
```
104105

106+
### Inheritance
107+
108+
The capture set of `this` of a class or trait also serves as an upper bound of the possible capture
109+
sets of extending classes
110+
```scala
111+
abstract class Root:
112+
this: Root^ => // the default, can capture anything
113+
114+
abstract class Sub extends Root:
115+
this: Sub^{a, b} => // ok, refinement {a, b} <: {cap}
116+
117+
class SubGood extends Sub:
118+
val fld: AnyRef^{a} = a // ok, {a} included in {a, b}
119+
120+
class SubBad extends Sub:
121+
val fld: IO^{io} = io // error, {io} not included in the this capture set {a, b}
122+
123+
class SubBad2 extends Sub:
124+
this: SubBad2^{io} => // error, self type SubBad2^{e} does not conform to Sub^{c, d}
125+
```
126+
127+
Generally, the further up a class hierarchy we go, the more permissive/impure the `this` capture set
128+
of a class will be (and the more restrictive/pure it will be if we traverse the hierarchy downwards).
129+
For example, Scala 3's top reference type `AnyRef`/`Object` conceptually has the universal
130+
capability
131+
```scala
132+
class AnyRef:
133+
this: AnyRef^ =>
134+
// ...
135+
```
136+
Similarly, pure `Iterator`s are subtypes of impure ones.
137+
105138
## Capture Tunneling
106139

107140
Consider the following simple definition of a `Pair` class:

0 commit comments

Comments
 (0)