Commit b2ba6dc
authored
Fix i19315: avoid calling
Fixes #19315.
The unsound code:
```scala
import language.experimental.captureChecking
trait Logger
case class Boxed[T](unbox: T)
// a horrible function, but it typechecks
def magic(l: Logger^): Logger =
class Foo:
def foo: Boxed[Logger^{this}] =
// for the following line to typecheck
// the capture checker assumes {l} <: {this}
Boxed[Logger^{this}](l)
val x = new Foo
val y = x.foo.unbox // y: Logger^{x}
val z: Logger = y // now the capability becomes pure
z
```
The `magic` function typechecks before this fix. It casts a capability
to a pure value, which is clearly unsound. The crux of the problem is
`Boxed[Logger^{this}](l)`, which relies on the subcapturing relation
`{l} <: {this}` enabled by the trick implemented `addOuterRefs`.
`addOuterRefs` augment a capture set that contains a self reference
(like `{this}`) with all outer references reachable from `this`. In this
case, the augmented set is `{this, l}`. The reasoning is that, any
captured outer references in the class can be rewritten into a field,
thus being a subcapture of `{this}`:
```
class Foo:
val this_l: Logger^{l} = l
def foo: Boxed[Logger^{this}] = Boxed(this.this_l)
```
But the problem with this unsound example is that, the reference to `l`
is boxed, so `l` is not captured by the class. Therefore, the above
rewriting mismatches with the actual situation.
This PR proposes a simple fix, which simply disable `addOuterRefs` when
box adaptation happens. This is of course imprecise, but all tests pass
with this fix.addOuterRefs when the actual type is box-adapted (#19323)File tree
2 files changed
+20
-1
lines changed- compiler/src/dotty/tools/dotc/cc
- tests/neg-custom-args/captures
2 files changed
+20
-1
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
847 | 847 | | |
848 | 848 | | |
849 | 849 | | |
850 | | - | |
| 850 | + | |
851 | 851 | | |
852 | 852 | | |
| 853 | + | |
| 854 | + | |
| 855 | + | |
| 856 | + | |
853 | 857 | | |
854 | 858 | | |
855 | 859 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
0 commit comments