diff options
| author | Brian Koropoff <bkoropoff@gmail.com> | 2014-10-07 20:04:45 -0700 |
|---|---|---|
| committer | Brian Koropoff <bkoropoff@gmail.com> | 2014-10-16 17:29:44 -0700 |
| commit | 9094aabb12573c7a4de11144f3b80bf7126e6e1b (patch) | |
| tree | 036e1694bd8c93065fec54a8236796624604b415 /src/rustllvm/RustWrapper.cpp | |
| parent | 1868a262f36a57fa6bac96c2f173129c57d4e62f (diff) | |
| download | rust-9094aabb12573c7a4de11144f3b80bf7126e6e1b.tar.gz rust-9094aabb12573c7a4de11144f3b80bf7126e6e1b.zip | |
Fix soundness bug in treatment of closure upvars by regionck
- Unify the representations of `cat_upvar` and `cat_copied_upvar`
- In `link_reborrowed_region`, account for the ability of upvars to
change their mutability due to later processing. A map of recursive
region links we may want to establish in the future is maintained,
with the links being established when the kind of the borrow is
adjusted.
- When categorizing upvars, add an explicit deref that represents the
closure environment pointer for closures that do not take the
environment by value. The region for the implicit pointer is an
anonymous free region type introduced for this purpose. This
creates the necessary constraint to prevent unsound reborrows from
the environment.
- Add a note to categorizations to make it easier to tell when extra
dereferences have been inserted by an upvar without having to
perform deep pattern matching.
- Adjust borrowck to deal with the changes. Where `cat_upvar` and
`cat_copied_upvar` were previously treated differently, they are
now both treated roughly like local variables within the closure
body, as the explicit derefs now ensure proper behavior. However,
error diagnostics had to be changed to explicitly look through the
extra dereferences to avoid producing confusing messages about
references not present in the source code.
Closes issue #17403. Remaining work:
- The error diagnostics that result from failed region inference are
pretty inscrutible and should be improved.
Code like the following is now rejected:
let mut x = 0u;
let f = || &mut x;
let y = f();
let z = f(); // multiple mutable references to the same location
This also breaks code that uses a similar construction even if it does
not go on to violate aliasability semantics. Such code will need to
be reworked in some way, such as by using a capture-by-value closure
type.
[breaking-change]
Diffstat (limited to 'src/rustllvm/RustWrapper.cpp')
0 files changed, 0 insertions, 0 deletions
