Thanks. I was a genuine question and you answered it well. For some reason I've internalized that closures can capture variables sometimes, but I guess I'm not sure the conditions in which that's true (or perhaps I've learned/mis-remembered the wrong lesson a long time ago.
If the code in the closure moves a value, then the closure becomes an FnOnce and does move the value out of the context. That's what you probably have in mind.
So, Rust does support partially-moving closures, and does so automatically.
But the converse is also true: Rust does not move values just because. If the code inside the closure doesn't move the context, then it will only move context if you use the `move` keyword (in which case the lifetime of the closure is not restricted by borrows of the context; Rust doesn't automatically move things to satisfy the closure's required lifetime, that's a manual decision process consistent with how Rust behaves in other places).
There's still one difference to the macro case: the closure borrows all the values at once. So if it needs &mut access to some variable in the context, you can't take another &mut to the same variable outside the closure as long as it is alive (as determined per what the non-lexical lifetime borrow checker can do). Those cases need to be worked around by instead passing in the &mut as a closure argument. Code deposited by macros is not subject to bundling all captures together, hence the borrow checker has more allowance to reduce the borrowing time of each borrow.
schneems|2 months ago
pflanze|1 month ago
So, Rust does support partially-moving closures, and does so automatically.
But the converse is also true: Rust does not move values just because. If the code inside the closure doesn't move the context, then it will only move context if you use the `move` keyword (in which case the lifetime of the closure is not restricted by borrows of the context; Rust doesn't automatically move things to satisfy the closure's required lifetime, that's a manual decision process consistent with how Rust behaves in other places).
There's still one difference to the macro case: the closure borrows all the values at once. So if it needs &mut access to some variable in the context, you can't take another &mut to the same variable outside the closure as long as it is alive (as determined per what the non-lexical lifetime borrow checker can do). Those cases need to be worked around by instead passing in the &mut as a closure argument. Code deposited by macros is not subject to bundling all captures together, hence the borrow checker has more allowance to reduce the borrowing time of each borrow.