You are trying to cast &dyn FnMut() to dyn FnMut(), which is not possible as &dyn FnMut() does not implement FnMut(). Your error message is slightly confusing, because of this blanket implementation of FnMut() for &T where T: Fn(). I honestly would consider changing your API in such a way that you let the user create the Box<dyn FnMut()> and pass it to ScopeExit::new, rather than &dyn FnMut(). I don't think there's a way to create a Box<dyn FnMut()> from a &dyn FnMut().
This wouldn't make any sense. &dyn FnMut() is limited time borrow, Box<dyn FnMut()> is unlimited owned type.
It's like taking one-year loan from bank and then giving that money to someone permanently.
In real world you would end up in jail, in Rust this lead to compile-time error.
P.S. Of course the opposite works fine, both in real world and in Rust: if you have own money (or have onwership of closure) then you can loan it to someone temporarily.
error[E0599]: the function or associated item `new` exists for struct `Box<dyn FnMut()>`, but its trait bounds were not satisfied
--> src/lib.rs:12:48
|
12 | ScopeExit { call_: Box::<dyn FnMut()>::new(call) }
| ^^^ function or associated item cannot be called on `Box<dyn FnMut()>` due to unsatisfied trait bounds
|
::: /home/shylock/.rustup/toolchains/stable-x86_64-unknown-linux-gnu/lib/rustlib/src/rust/library/core/src/ops/function.rs:163:1
|
163 | pub trait FnMut<Args: Tuple>: FnOnce<Args> {
| ------------------------------------------ doesn't satisfy `dyn FnMut(): Sized`
|
= note: the following trait bounds were not satisfied:
`dyn FnMut(): Sized`
For more information about this error, try `rustc --explain E0599`.
a little explanation: you actually create a box of the generic type (of the FnMut() bound), then the box is unsize coerced into Box<dyn FnMut()>, so the code with all types annotated should be: