-
Notifications
You must be signed in to change notification settings - Fork 1.1k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Change handling of curried function types in capture checking #18131
Conversation
This is best reviewed commit by commit |
f6389d0
to
ffee8bd
Compare
Some new comments, simplifications, syntax tweaks
And further simplifications and comments
Remove automatic insertion of captured in curried function types from left to right. They were sometimes confusing and with deep capture sets are counter-productive now.
- Don't widen actual in adaptBoxed if expected is a singleton type - Don't allow singleton types with capture sets (the theory does not allow them either)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Otherwise LGTM!
adapted | ||
else actual | ||
if expected.isSingleton && actual.isSingleton then | ||
println(i"shot $actual $expected") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
println(i"shot $actual $expected") |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's deleted in follow-up commit in the other PR.
/** Reset `private` flags of parameter accessors so that we can refine them | ||
* in Setup if they have non-empty capture sets. Special handling of some | ||
* symbols defined for case classes. | ||
/** - Reset `private` flags of parameter accessors so that we can refine them |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
/** - Reset `private` flags of parameter accessors so that we can refine them | |
/** - Reset `private` flags of parameter accessors so that we can refine them |
Some meta-comments: currently only curried function closure stops capture propagation, but theoretically all function definitions could stop the propagation. For example: val test1: Int ->{} Int ->{io} Int =
x => y => {
io.use()
x + y
}
val test2: Int ->{} Int ->{io} Int =
x => {
def f(y: Int): Int =
io.use()
x + y
f
} By principle both cases should work but currently only the first one does. Could we make all function definitions stop the propagation of captures to allow cases like |
After playing with more examples I discovered a soundness issue introduced by this PR: trait Cap:
def use(): Unit
def withCap[sealed T](op: (x: Cap^) => T): T = ???
trait Box:
val get: () ->{} () ->{cap} Cap^
def main(): Unit =
val leaked = withCap: (io: Cap^) =>
class Foo extends Box, Pure:
val get: () ->{} () ->{io} Cap^ = () => () => io
new Foo
val bad = leaked.get()().use() // using a leaked capability This is because curried function stops the captures from being propagated to the class's |
# Conflicts: # compiler/src/dotty/tools/dotc/transform/Pickler.scala
ffee8bd
to
c7a5350
Compare
Convert some standard library classes to capture checking. The converted classes are represented as tests. Initially, the `Iterator` and `IterableOnce` classes are converted. UPDATE: By now, we have quite a few more, including List, ListBuffer, View, and all their super classes and traits. Also change capture checker to facilitate the conversion. The main changes are about better interop with classes that are not (yet) capture checked. Based on #18131
Implements the proposed treatment in cc-paths.