Expand description
In rust, closures behave like ADTs that implement the FnOnce/FnMut/Fn traits automatically.
Here we convert closures to a struct containing the closure’s state (upvars), along with matching trait impls and fun decls (e.g. a Fn closure will have a trait impl for Fn, FnMut and FnOnce, along with 3 matching method implementations for call, call_mut and call_once).
For example, given the following Rust code:
pub fn test_closure_capture<T: Clone>() {
let mut v = vec![];
let mut add = |x: &u32| v.push(*x);
add(&0);
add(&1);
}
We generate the equivalent desugared code:
struct {test_closure_capture::closure#0}<'a, T: Clone> (&'a mut Vec<u32>);
// The 'a comes from captured variables, the 'b comes from the closure higher-kinded signature.
impl<'a, 'b, T: Clone> FnMut<(&'b u32,)> for {test_closure_capture::closure#0}<'a, T> {
fn call_mut<'c>(&'c mut self, arg: (&'b u32,)) {
self.0.push(*arg.0);
}
}
impl<'a, 'b, T: Clone> FnOnce<(&'b u32,)> for {test_closure_capture::closure#0}<'a, T> {
type Output = ();
...
}
pub fn test_closure_capture<T: Clone>() {
let mut v = vec![];
let mut add = {test_closure_capture::closure#0} (&mut v);
state.call_mut(&0);
state.call_mut(&1);
}