I have a trait Foo
. This has a method which takes a generic type implementing Bar
and is therefore not object safe:
trait Bar {}
trait Foo {
fn foofunc<B: Bar>(&self, b: B);
}
I want to make the trait Foo
object safe. I gather the usual way to do this is to wrap it in a new, object-safe, trait (see here). Something along the lines of:
trait FooObjectSafe<B>
where B: Bar,
{
fn foofunc(&self, b: B);
}
impl<B, F> FooObjectSafe<B> for F
where B: Bar,
F: Foo,
{
fn foofunc(&self, b: B) {
Foo::foofunc(self, b)
}
}
This seems very limiting however. If there is a function use_foo
which takes a generic type implementing Foo
, then it cannot be used with FooObjectSafe
without changing its signature (I don't want to do this as in practise these functions come from different modules and are very divorced from one another):
struct BarImpl;
impl Bar for BarImpl {}
struct FooImpl;
impl Foo for FooImpl {
fn foofunc<B: Bar>(&self, b: B) {}
}
fn main() {
let foos = [
Box::new(FooImpl{}) as Box<dyn FooObjectSafe<BarImpl>>,
Box::new(FooImpl{})
];
use_foo(foos[0]);
}
results in the error
error[E0277]: the trait bound `Box<dyn FooObjectSafe<BarImpl>>: Foo` is not satisfied
--> src/main.rs:43:13
|
43 | use_foo(foos[0]);
| ------- ^^^^^^^ the trait `Foo` is not implemented for `Box<dyn FooObjectSafe<BarImpl>>`
| |
| required by a bound introduced by this call
|
= help: the trait `Foo` is implemented for `FooImpl`
note: required by a bound in `use_foo`
--> src/main.rs:9:14
|
8 | fn use_foo<F>(foo: F)
| ------- required by a bound in this
9 | where F: Foo,
| ^^^ required by this bound in `use_foo`
For more information about this error, try `rustc --explain E0277`.
error: could not compile `playground` due to previous error
Is there a better way to do this? I suspect I'm making some architectural faux pas here, but what exactly?