-
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
Add capture checking to some standard library classes #18192
Conversation
c0a7fc1
to
1613aac
Compare
ddb121e
to
a32b6d4
Compare
1c6c09c
to
bae1a9a
Compare
Add unsafeAssumePure method as an escape hatch which is more specific than a cast.
This would become a problem when adding fluid capture sets to FromJavaObject types. And it anyway gives better error messages.
The pickler test did not track whether capture checking was on. This meant that files with import language.experimental.captureChecking has to be compiled additionally with the capture checking setting -language.experimental.captureChecking to pass pickler tests. This made it impossible to test mixed code bases where some files require capture checking and others don't. We now use the previous setting of `CompilationUnit#needsCaptureChecking` when unpickling.
Similar to the treatment of WithPureFuns, we add an annotation WithCaptureChecks to toplevel classes if they were compiled with capture checking on. We also keep a flag on all classes so that we can find out fast whether the class was capture checked or not. However, that flag is not pickled. It is instead reconstituted by the unpickler when it sees the WtihCaptureChecks annotation.
When interacting with files that are not captue checked, we should assume that types can have arbitrary capture sets. This is analogous to interacting with non-null checked files, where we also assume that types in the interface can be null or not. This commit enables interop for normal rechecking by decorating types coming from sources that are not capture-checked with a special `Fluid` capture set. This set both super- and subcaptures any other capture set.
Supress bounds checking in CheckCaptures if the type constructor of an applied type has not been compiled with capture checking.
It seems it's no longer needed.
The original versions of Iterator and IterableOnce before adding capture checking annotations
- Also add Fluid to function types - Add Fluid recursively in arguments of fluidified types - But stop when a capturing type is encountered Also, fix needsVariable for FromJavaObject. FromJavaObject should behave like Any (i.e. no capture set variable needs to be added).
User-defined value classes should be able to capture capabilities
Otherwise we force purity where none might exist.
Members andThen, compose, curried, tupled of function types are now given special types for capture checking that reflect fine-grained capture dependencies.
With the new gradual typing using Fluid capture sets, this should be no longer needed.
def knownSize: Int = -1 | ||
} | ||
|
||
final class IterableOnceExtensionMethods[A](private val it: IterableOnce[A]) extends AnyVal { |
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.
Should it
be impure? otherwise the extension methods only apply on pure IterableOnce
s.
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.
I left it like that since all extension methods are deprecated anyway,
As `Map` shows, it's possible that an overriding check is from an external non-capture checked subclass member against a currently compiled & capture-checked superclass member. Hence, we have to add Fluid sets to either part of an overriding check if that part is not compiled with capture checking. This allows to include collection/Map in the set of capture checked stdlib sources.
Plus all supertraits of ListBuffer
There was a subtle difference which causeed the stdlib tests to crash under -Xprint:cc
Without this, we get stray capture sets in match selectors if the match is not exhaustive.
Observations of shortcomings so far:
|
@Linyxus This is about as far as I want to push it for now. Can you give it a rough review? I think you need to look only at the changes to the compiler itself; the test programs don't matter so much. It would be good to get it in fast since there are a lot of accumulated changes and other stuff we do with capture checking should build on these. |
Thanks for the heads-up! I'll do the review right away. |
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.
LGTM!
So it seems that /cc @odersky |
These are symlinks. Maybe Windows does not know about them and interprets them literally? |
I pushed a new PR that should fix the problem. |
Convert some standard library classes to capture checking. The converted classes are represented as tests.
Initially, the
Iterator
andIterableOnce
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