-
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
Alternative scheme for cc encapsulation #18899
Conversation
We went from 104 uses of @uncheckedCaptures in stdlib collections to 1 (a low-level class inside LazyListIterable). |
This adds reach capabilities x* as described in the proposal.
Since it is never necessary to write `cap` explicitly, there's no need to treat the identifier as a soft keyword.
This means that no type parameter can be instantiated with a type that captures cap covariantly or invariantly in its type. Two exceptions/special cases: - Type arguments for isInstanceOf and asInstanceOf are excluded, they can capture cap anywhere. - Refining variables in class types can still contain cap since they describe what comes from the constructor. Test reclassifications: - i15922.scala was moved to pending. Not clear whether this should compile, and what changes would be necessary to get it there. - future-traverse.scala was moved to pending. Not clear how to make this compiler. - i15749a.scala was moved to neg. The issue description seems to indicate that the test should not compile, but I am not sure what the outcome should be.
For some reason, http4s in the CB fails compilation otherwise. It's not clear what the failure has to do with the addition of $reach to Any, but it goes away when $reach has Method flag.
That way it does not show up in completion suggestions
- use isTrackableRef everywhere for discrimination (instead of just checking the CaptureRef type) - streamline treatment of reach refs through `stripReach`
- For i15922, it should not work, as both bad1 and bad2 leak scoped capabilities. It is moved to neg tests. - For future-traverse.scala, we could make it work this way. Previously it won't compile because we instantiated the type parameter of `successful` with a universal capability, but actually we needn't do that: we could well pick a local reach capability, as is done in this commit. - For i15749a.scala, it should work but sadly not right now, due to a limitation of our current implementation.
The commit I just pushed is a reclassification of tests mentioned in #18899. There are rough edges still: we could have made i15749a work, but we could not right now due to a expressiveness limitation of the current implementation. To recap, i15749a previously stops working because it instantiates a type parameter with an instance containing def forceWrapper[A](mx: Wrapper[Unit ->{cap} A]): Wrapper[A] =
strictMap[Unit ->{cap} A, A](mx)(t => force[A](t)) // error but we needn't have done that as we could instead instantiate the type parameter with That requires typing Such expressiveness limitation extends to church-encoding-like patterns in general, where a church-encoded datatype takes an impure operation to act on the encapsulated data. Another example on church-encoded pairs: trait IO
type Pair[+T, +U] = [R] -> (op: (T, U) => R) -> R
def cons[T, U](a: T, b: U): Pair[T, U] = [R] => op => op(a, b)
def car[T, U](p: Pair[T, U]): T = p((a, b) => a)
def cdr[T, U](p: Pair[T, U]): U = p((a, b) => b)
def foo(p: Pair[IO^, IO^]): Unit =
var x: IO^{p*} = null
x = car[IO^{p*}, IO^{p*}](p) // error Neither could it be compiled as the compiler currently cannot type There is hope: these cases can actually be detected. For a type like |
Very nice analysis! |
@Linyxus Should we merge this now and work on the improvements in separate PRs? |
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!
Starting with a design document for exploring possible alternatives to the current encapsulation scheme in cc, this PR
implements a different, simpler scheme from what we had before.