I have the following code:
fn test() -> (impl FnMut(&mut u8), impl FnMut(&mut u8)) {
let a = |v: &mut u8| {*v = 0};
let b = move |v: &mut u8| { a(v); println!("{}", v) };
(a, b)
}
fn main() {
let mut val: u8 = 10;
let (mut a, mut b) = test();
b(&mut val);
val = 10;
a(&mut val);
assert!(val == 0);
}
(this is a MWE based on something I encountered in the wild). Now, this works as expected, but I don't really understand why this even compiles: We need to move a into b to use it there (otherwise, one gets a compiler error), but somehow, we can still return a afterwards and use it without any issue. Doesn't this go against the basic principles of the borrow checker? What is going on here?
The one explanation I could imagine is that the actual a closure somehow gets coerced to a function pointer with a static lifetime, and it is just this pointer that is being moved (i.e. copied) into the b closure. However, I have no way to verify this.