Reputation: 43
I have two generic traits that need to be passed to each other as type parameters. The code boils down to this
pub trait Entity<T: EntityRenderer<Self>>
where Self: Sized
{
fn get_renderer(&self) -> &T;
}
pub trait EntityRenderer<T: Entity<Self>>
where Self: Sized
{
fn get_animation_frame(&T) -> u32;
}
Entity
needs to know what type it's EntityRenderer
is, and vice versa. Later, I have
entities: Vec<Box<Entity>>
This is an issue, as I can't resolve the type parameter of Entity
. I also can't make either of the functions which need the type parameter generic, because Rust's compiler won't let traits with generic methods become trait objects.
Is there any workaround? Or am I violating some sort of memory safety law that I am unaware of?
Upvotes: 0
Views: 1029
Reputation: 65937
You can't do this with trait objects, because trait objects erase the real type of the underlying object. The giveaway is that, in order to use Self
on the bound for T
, you need the bound Self: Sized
, yet that very bound disables the ability to use trait objects (like Box<Entity>
). And we haven't even addressed the fact that Box<Entity>
doesn't even specify a value for the type parameter T
on Entity
.
It looks like Entity
(and maybe EntityRenderer
too) should use an associated type instead of a type parameter. However, associated types won't solve your original problem; you'll get essentially the same problem, because you'd still need the Self: Sized
bound and because you'd need to specify a value for the associated type on the trait object (Box<Entity<Renderer=???>>
).
Upvotes: 1