Skip to content

Commit

Permalink
Handle borrows of unions in NLL
Browse files Browse the repository at this point in the history
  • Loading branch information
KiChjang committed Oct 6, 2017
1 parent bc430eb commit 38d3699
Showing 1 changed file with 18 additions and 0 deletions.
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

0 comments on commit 38d3699

Please sign in to comment.