Skip to content

Handle borrows of unions in NLL #2168

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

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 18 additions & 0 deletions text/2094-nll.md
Original file line number Diff line number Diff line change
Expand Up @@ -1694,6 +1694,16 @@ if they meet one of the following criteria:
- so: writing a path like `a` is illegal if `a.b` is borrowed
- but: writing `a` is legal if `*a` is borrowed, whether or not `a`
is a shared or mutable reference
- the loan path has a **shallow prefix** `<base>.<field1>` that accesses a
field of a union, and `lvalue` has a prefix of the form `<base>.<field2>`
for a _different_ field of the same base union.
- so: if `s.u` is a union with distinct fields `a` and `b`, shallowly
accessing a path `s.u.a.x` is illegal if `s.u.b` or `s.u.b.y` is borrowed.
In here, `<base>` is `s.u`, `<field1>` is `b` and `<field2>` is `a`.
- but: unless `s.u.a` is _also_ a union, the access `s.u.a.x` is _legal_
if `s.u.a.z` is borrowed, because the same union field is used in both borrows.
- the prefix of `lvalue` can be an arbitrary prefix - if `s.u.b.w` is borrowed,
then it is illegal to shallowly access `*(*s.u.a.z).t`

For **deep** accesses to the path `lvalue`, we consider borrows relevant
if they meet one of the following criteria:
Expand All @@ -1707,6 +1717,14 @@ if they meet one of the following criteria:
- so: reading a path like `a` is illegal if `a.b` is mutably
borrowed, but -- in contrast with shallow accesses -- reading `a` is also
illegal if `*a` is mutably borrowed
- the loan path has a **supporting prefix** `<base>.<field1>` that accesses a
field of a union, and `lvalue` has a prefix of the form `<base>.<field2>` for
a _different_ field with the same base union.
- so: if `s.u` is a union with distinct fields `a` and `b`, deeply accessing
a path `s.u.a.x` is illegal if `s.u.b`, `s.u.b.w`, or (in contrast with
shallow accesses, and as long as both dereferences are of the form `&mut T`)
`*(*s.u.b.w).t` is borrowed. In here, `<base>` is `s.u`, `<field1>` is `b`,
and `<field2>` is `a`.

**Dropping an lvalue LV.** Dropping an lvalue can be treated as a DEEP
WRITE, like a move, but this is overly conservative. The rules here
Expand Down