-
Notifications
You must be signed in to change notification settings - Fork 1.1k
Improve handling of consume in class constructors #24424
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
base: main
Are you sure you want to change the base?
Conversation
| val _: A1^{cap, b} = a1 | ||
| println(b) // OK since a1's type mentions `b` explicitly | ||
| val a2 = A2(b) | ||
| val _: A2^{cap, b} = a2 |
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.
| val _: A2^{cap, b} = a2 | |
| val _: A2^ = a2 |
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.
Is this intentional? It doesn't seem to matter if it's {cap, b} or {cap}. Or is the point to show that mentioning b explicitly as in A1 above doesn't influence the outcome?
| println(b) // error | ||
| println(a1) // error, since `b` was consumed before | ||
| println(a2) // OK since b belongs to a2 | ||
|
|
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.
Trying println(a2.b) at this point yields a separation failure. But why? The b should be owned by a2 now. If this is as intended, it means that consume on a val constructor parameter makes the field inaccessible.
| && !implied.isAlwaysEmpty | ||
| && argType.captureSet.subCaptures(allCaptures) | ||
| // A consume parameter of a constructor will be hidden in the implied fresh of the | ||
| // class if there is one. Example: |
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'm trying to understand what should happen when the if there is one part is not true.
Say, in the below test file, if we let A1 and A2 have no implied fresh (IIUC):
class A1(val b: B^)
class A2(consume val b: B^)Then it exhibits the expected errors, plus it complains about
val _: A2^{cap, b} = a2 and println(a2) with the same error message:
Separation failure: Illegal access to (a2 : A2{val b: B^{b²}}^{b²}), which was passed to a
|consume parameter or was used as a prefix to a consume method on line 18
|and therefore is no longer available.
|
|where: b is a value in class A2
| b² is a value in method TestWhy is accessing a2 forbidden now?
Independently of whether an error is expected or not: The error message itself is confusing, because a2 neither was "passed to a consume parameter" nor "was used as a prefix to a consume method".
Two changes:
val _ = elike just the expressionefor separation checking.