I’m trying to use a callback function on a trait object. I reduced my problem to the following code (playpen):
trait Caller {
fn call(&self, call: fn(&Caller)) where Self: Sized {
call(self)
}
}
struct Type;
impl Caller for Type {}
fn callme(_: &Caller) {}
fn main() {
let caller: Box<Caller> = Box::new(Type);
caller.call(callme); // does not work
//callme(&*caller); // works
}
which results in
<anon>:14:12: 14:24 error: the trait `core::marker::Sized` is not implemented for the type `Caller` [E0277]
<anon>:14 caller.call(callme); // does not work
^~~~~~~~~~~~
Adding a Sized bound to Caller results in:
<anon>:3:14: 3:18 error: cannot convert to a trait object because trait `Caller` is not object-safe [E0038]
I really don’t understand why I need the Sized bound on the trait. Funnily it works if I use the callback directly. How do I get this to work?
Edit: Thanks to the answer I now came up with a nice solution
trait Caller {
fn borrow(&self) -> &Caller;
fn call(&self, call: fn(&Caller)) {
call(self.borrow())
}
}
struct Type;
impl Caller for Type {
fn borrow(&self) -> &Caller { self }
}
fn callme(_: &Caller) {}
fn main() {
let caller: Box<Caller> = Box::new(Type);
caller.call(callme);
}