-
Notifications
You must be signed in to change notification settings - Fork 1.6k
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
Handle borrows of unions in NLL #2168
Conversation
text/2094-nll.md
Outdated
@@ -1563,6 +1563,8 @@ follows: | |||
|
|||
- any loans whose region does not include P are killed; | |||
- if this is a borrow statement, the corresponding loan is generated; | |||
- if the borrow contains a union field, loans are generated for all |
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.
This is vague ("if a borrow contains a union field"), and doesn't look like the right place to specify borrows of union fields.
I think the right place to specify the handling of unions is the place describing
And I think we can write something as follows
And on the supporting section:
|
@arielb1 So from the union RFC, we have this property:
In your example, that would also mean that
|
Disregard my previous comment, the case that I was concerned about is covered by the " |
Updated the text to display a more correct version of handling union fields. |
Specifying borrowing errors through loan path "intersection" seems significantly more complex than recursive definition " |
Oh my. |
OK, sorry for coming late to the party. I finally carved out some time to read these changes. I agree that these sound roughly correct. I was, however, curious if we could frame this check in a more generic way -- essentially, the key question we are testing here is whether two paths are "disjoint" (i.e., refer to distinct memory). I was thinking we could frame this in terms of some inference rules. For fun, I typed these up in Prolog, and you can try them out here. The rules are basically like this: /* Two distinct variables are disjoint */
disjoint(var(V0), var(V1)) :- V0 \= V1.
/* Two paths `p.f` and `p.g` are disjoint
* if the fields `f` and `g` are disjoint. */
disjoint(field(P, F0), field(P, F1)) :- disjoint_fields(F0, F1).
/* Two paths `p.f` and `q` are disjoint
* if `p` is disjoint from `q`. */
disjoint(field(P0, _), P1) :- disjoint(P0, P1).
disjoint(P0, field(P1, _)) :- disjoint(P0, P1). The rules for disjoint fields are then: /* Two distinct fields in the same struct are disjoint. */
disjoint_fields(F0, F1) :-
type_of(F0, S),
type_of(F1, S),
is_struct(S),
F0 \= F1.
/* Fields declared in two distinct types are disjoint. */
disjoint_fields(F0, F1) :-
type_of(F0, S0),
type_of(F1, S1),
S0 \= S1. This seems to behave like I expect -- I included a number of examples in the link above, including rust-lang/rust#45157 (that's the last example, I believe). When I run them, they seem to yield true/false as I expect. =) What I like about this formulation is that it scales quite readily to supporting fields in traits -- we simply have to make the I'm not proposing that we necessarily implement the rules like this, in any case, but I think it might be a useful way to specify them. I'm not sure yet if this PR is equivalent to the rules I wrote above -- I suspect it is, but I ran out of my quota allotted to reading and thinking here and have to go and get ready for Rust Belt Rust! =) EDIT: (Incidentally, turning this intuition regarding union into borrowck rules is a bit harder than I expected. It's kind of the inverse of the existing rules, which specify what is illegal, since the disjoint formulation come at it from the POV of specifying what is legal. It seems like a better way to go, but it's making my head hurt. Perhaps in the morning.) |
A meta question: should we keep updating the RFC here, or in the nll-rfc repo? I think I'd prefer to iterate on the nll-rfc repo (which I could move to rust-lang-nursery or something), just because these are narrow questions and I don't know that we need to use the full RFC repo. And we are still tracking some other unresolved questions there as well. But I'm kind of open to either. |
Superseded by #2174. |
This is a small addition to RFC2094 so that we can handle unions as outlined in RFC1444.
Rendered