I am in a situation where I want some objects to implement a trait, say "Base", and some other objects will implements a trait "Super". The Super trait also has to be generic for T : Base so that I can automatically implement parts of Super based on which Base it was specialized with. Now this seems to work fine with the following trivial example
trait Base {
fn say_hi() -> &'static str;
}
struct BaseOne {}
struct BaseTwo {}
impl Base for BaseOne {
fn say_hi() -> &'static str {
"hi!"
}
}
impl Base for BaseTwo {
fn say_hi() -> &'static str {
"hello!"
}
}
trait Super<T: Base> {
fn say_hi(&self) -> &'static str {
T::say_hi()
}
}
struct SuperOne;
struct SuperTwo;
impl Super<BaseOne> for SuperOne {}
impl Super<BaseTwo> for SuperTwo {}
My problem comes in with my next requirement, which is that I want to be able to store a vector of objects which implement Super, regardless of which Base it is specialized for. My idea for this is to create a trait that covers all Supers, such as the AnySuper trait below
trait AnySuper {
fn say_hi(&self) -> &'static str;
}
impl<T> AnySuper for dyn Super<T> where T : Base {
fn say_hi(&self) -> &'static str {
Super::say_hi(self)
}
}
And then store a vector of Box such as in the example below
fn main() {
let one = Box::new(SuperOne);
let two = Box::new(SuperTwo);
let my_vec: Vec<Box<dyn AnySuper>> = Vec::new();
my_vec.push(one);
my_vec.push(two);
}
But unfortunately that fails with the following error
error[E0277]: the trait bound `SuperOne: AnySuper` is not satisfied
--> src/main.rs:52:17
|
52 | my_vec.push(one);
| ^^^ the trait `AnySuper` is not implemented for `SuperOne`
|
= note: required for the cast to the object type `dyn AnySuper`
error[E0277]: the trait bound `SuperTwo: AnySuper` is not satisfied
--> src/main.rs:53:17
|
53 | my_vec.push(two);
| ^^^ the trait `AnySuper` is not implemented for `SuperTwo`
|
= note: required for the cast to the object type `dyn AnySuper`
Which is a bit strange because in my mind I have implemented AnySuper for all Super<T>. So my question is, am I doing something fundamentally wrong or is there just an issue with my syntax?
P.S. I have set up a playground with this code at https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=a54e3e9044f1edaeb24d8ad934eaf7ec if anyone wants to play around with it.