Skip to content

Commit 38d3699

Browse files
committed
Handle borrows of unions in NLL
1 parent bc430eb commit 38d3699

File tree

1 file changed

+18
-0
lines changed

1 file changed

+18
-0
lines changed

text/2094-nll.md

+18
Original file line numberDiff line numberDiff line change
@@ -1694,6 +1694,16 @@ if they meet one of the following criteria:
16941694
- so: writing a path like `a` is illegal if `a.b` is borrowed
16951695
- but: writing `a` is legal if `*a` is borrowed, whether or not `a`
16961696
is a shared or mutable reference
1697+
- the loan path has a **shallow prefix** `<base>.<field1>` that accesses a
1698+
field of a union, and `lvalue` has a prefix of the form `<base>.<field2>`
1699+
for a _different_ field of the same base union.
1700+
- so: if `s.u` is a union with distinct fields `a` and `b`, shallowly
1701+
accessing a path `s.u.a.x` is illegal if `s.u.b` or `s.u.b.y` is borrowed.
1702+
In here, `<base>` is `s.u`, `<field1>` is `b` and `<field2>` is `a`.
1703+
- but: unless `s.u.a` is _also_ a union, the access `s.u.a.x` is _legal_
1704+
if `s.u.a.z` is borrowed, because the same union field is used in both borrows.
1705+
- the prefix of `lvalue` can be an arbitrary prefix - if `s.u.b.w` is borrowed,
1706+
then it is illegal to shallowly access `*(*s.u.a.z).t`
16971707

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

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

0 commit comments

Comments
 (0)