Hello,
the code below implements a simple Callback
struct that contains a boxed FnMut
. I implemented DerefMut
to be able to call it.
The call through DerefMut
however only works when not using a &mut
reference (using the &mut *
trick I found here).
The error message when using a &mut
reference is baffling, because it talks about &
references, which I can only explain when Deref
is called instead of DerefMut
.
Is there a way to make this work when I already have a &mut
reference, or must I explicitly call deref_mut()
?
use std::ops::{Deref, DerefMut};
struct Callback(Box<dyn FnMut()>);
impl Callback {
fn new(callback: impl FnMut() + 'static) -> Self {
Self(Box::new(callback))
}
}
impl Deref for Callback {
type Target = Box<dyn FnMut()>;
fn deref(&self) -> &Self::Target {
&self.0
}
}
impl DerefMut for Callback {
fn deref_mut(&mut self) -> &mut Self::Target {
&mut self.0
}
}
fn main() {
let mut cnt = 0;
let mut callback = Callback::new(move || {
cnt += 1;
println!("Test {}", cnt);
});
// This works.
(&mut *callback)();
let callback_ref: &mut Callback = &mut callback;
// This works, but I want to avoid the explicit call to deref_mut.
callback_ref.deref_mut()();
// This one does not.
// callback_ref();
// This one also does not work, but I expected it to.
(&mut *callback_ref)();
}
Errors:
Compiling playground v0.0.1 (/playground)
error[E0596]: cannot borrow data in a `&` reference as mutable
--> src/main.rs:44:5
|
44 | (&mut *callback_ref)();
| ^^^^^^^^^^^^^^^^^^^^ cannot borrow as mutable
error: aborting due to previous error
For more information about this error, try `rustc --explain E0596`.
error: Could not compile `playground`.
To learn more, run the command again with --verbose.