diff options
| author | bors <bors@rust-lang.org> | 2018-05-04 15:00:13 +0000 |
|---|---|---|
| committer | bors <bors@rust-lang.org> | 2018-05-04 15:00:13 +0000 |
| commit | 91db9dcf3730207f63b3dfc33b2c438a769b7517 (patch) | |
| tree | 2d2133016841d8239c831926c669b66cf24581f3 /src/test/incremental/thinlto | |
| parent | 0bfe3072cb5d181e4f60bf1033c8d81239a28385 (diff) | |
| parent | 930e76e2af5c1ba9f91240da5de20049b52e739c (diff) | |
| download | rust-91db9dcf3730207f63b3dfc33b2c438a769b7517.tar.gz rust-91db9dcf3730207f63b3dfc33b2c438a769b7517.zip | |
Auto merge of #49870 - pnkfelix:issue-27282-immut-borrow-all-pat-ids-in-guards, r=nikomatsakis
Immutably and implicitly borrow all pattern ids for their guards (NLL only)
This is an important piece of rust-lang/rust#27282.
It applies only to NLL mode. It is a change to MIR codegen that is currently toggled on only when NLL is turned on. It thus affect MIR-borrowck but not the earlier static analyses (such as the type checker).
This change makes it so that any pattern bindings of type T for a match arm will map to a `&T` within the context of the guard expression for that arm, but will continue to map to a `T` in the context of the arm body.
To avoid surfacing this type distinction in the user source code (which would be a severe change to the language and would also require far more revision to the compiler internals), any occurrence of such an identifier in the guard expression will automatically get a deref op applied to it.
So an input like:
```rust
let place = (1, Foo::new());
match place {
(1, foo) if inspect(foo) => feed(foo),
...
}
```
will be treated as if it were really something like:
```rust
let place = (1, Foo::new());
match place {
(1, Foo { .. }) if { let tmp1 = &place.1; inspect(*tmp1) }
=> { let tmp2 = place.1; feed(tmp2) },
...
}
```
And an input like:
```rust
let place = (2, Foo::new());
match place {
(2, ref mut foo) if inspect(foo) => feed(foo),
...
}
```
will be treated as if it were really something like:
```rust
let place = (2, Foo::new());
match place {
(2, Foo { .. }) if { let tmp1 = & &mut place.1; inspect(*tmp1) }
=> { let tmp2 = &mut place.1; feed(tmp2) },
...
}
```
In short, any pattern binding will always look like *some* kind of `&T` within the guard at least in terms of how the MIR-borrowck views it, and this will ensure that guard expressions cannot mutate their the match inputs via such bindings. (It also ensures that guard expressions can at most *copy* values from such bindings; non-Copy things cannot be moved via these pattern bindings in guard expressions, since one cannot move out of a `&T`.)
Diffstat (limited to 'src/test/incremental/thinlto')
0 files changed, 0 insertions, 0 deletions
