Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
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 #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`.)
- Loading branch information