Let me start with a simple and very valid requirement: wrap a FnOnce() into a struct, so we can have the Finally semantics.
Today we write:
struct Finally<F:FnOnce()>(F);
impl<F:FnOnce()> Drop for Finally<F> {
fn drop(&mut self) {
unsafe {
(std::mem::replace(&mut self.0, std::mem::uninitialized()))()
}
}
}
fn main() {
let finally = Finally(|| println!("finally!"));
}
To allow suppress the function call though, it is being very tricky. I think the best you can do is use another trait rather than FnOnce.
Now with this rfc, we write
struct Finally<F>(F) where F:FnOnce();
impl<F:FnOnce()> Destruct for Finally<F> {
#[match]
fn destruct(self) {
(self.0)();
}
}
fn main() {
let finally = Finally(|| println!("finally!"));
}
This is clearly much easier and intuitive. To suppress the call is also easy:
let finally = Finally(|| println!("finally!"));
let f = finally.0; // the closure was moved out, and so the call is suppressed