So: we don't like move
closures, in general. And we don't think moving the whole binding is harmful. But it needs to be done in a way that makes sense. But thanks to that thread we feel like we can come up with an even simpler set of rules: move
just makes closures move the binding where they'd otherwise borrow it.
if there are no closures or the move
is implicit, the compiler warns of unnecessary move
. e.g.:
let move x = foo; // warning: unused `move`
let y = x;
or
let move x = foo; // warning: unused `move`
let y = || drop(x);
as a bonus, these semantics can be implemented without introducing movable bindings!
let move x = foo;
let y = || x.foo(); // value moved here
x // error: use of moved value
this could then be changed to move the whole binding in the future. but it would solve some of the annoyances we personally have with move
closures. ^^
we think with movable bindings, the tricky part is e.g.:
let x = 1;
let move x = foo;
let y = || {
let move x = x;
let z = || x.foo();
// what is `x` here?
}
// obviously `x` here is `let x = 1;`
because it only moves into the next closure, so you need to move it again. with del x
this wouldn't be an issue but that one causes issues with pin_mut!
due to a bug in .pin_mut
where it introduces the backing binding into the user's scope