rust-lang/rust — pull request #16009 by pcwalton (2014-07-26 17:55:09+00:00)
Title: librustc: WIP patch for upgrading the way rvalues are treated.

WIP. Do not merge.

@nikomatsakis I'd like to get your feedback on this. I've implemented a patch which fixes the problem, but it has some nasty fallout in other parts of the codebase.

I first tried to make all rvalues treated like lvalues. This ran into problems with method chaining: `foo.bar().baz()` would not work anymore if `baz` required `&mut self`, as it thought it was a double borrow. I believe this is because of the rvalue temporary rules.

The next thing, which is in this patch, was to formulate the notion of "aliasable rvalues". These are rvalues that could be aliasable because they're about to be unpacked into a pattern. Local initializers, match values, and for loop heads fall into this list. This causes a few strange errors:

/Users/pcwalton/Source/rust/src/libcollections/treemap.rs:554:17: 554:18 error: cannot move out of `` because it is borrowed
/Users/pcwalton/Source/rust/src/libcollections/treemap.rs:554 let n: &mut TreeNode = &mut **n;
^
/Users/pcwalton/Source/rust/src/libcollections/treemap.rs:554:42: 554:50 note: borrow of `*` occurs here
/Users/pcwalton/Source/rust/src/libcollections/treemap.rs:554 let n: &mut TreeNode = &mut **n;

This may be related to the rvalue scope extension rules. I haven't dug into that to see whether it's the case.

Any thoughts as to the right way to go here?