use std::mem::replace;
fn main() {
let mut v = 0;
// let old_v = replace(&mut v, v + 1); // error[E0503]: cannot use `v` because it was mutably borrowed
let p = &mut v;
let old_v = replace(p, *p + 1); // this works fine
assert_eq!(0, old_v);
assert_eq!(1, v);
}
I can understand why replace(&mut v, v + 1) causes the error, but I don't understand why replace(p, *p + 1) passes.
I found the subtle difference by accident.
Is there any explanation about this? Thanks in advance.
Well, the arguments get prepped from left to right, and then the function gets called. So in the first version it's something like...
let arg0 = &mut v;
let arg1 = v + 1;
let old_v = replace(arg0, arg1);
And that gives the same error -- using v in v+1 invalidates the mutable borrow. Where as the new version is
let arg0 = &mut v;
let arg1 = *arg0 + 1;
let old_v = replace(arg0, arg1);
And there is no direct use of v to invalidate the borrow (arg0). You're utilizing the borrow for a short period to do the addition, and then again when you call the function.