When compiling the following code:
trait RenderTarget {}
struct RenderWindow;
impl RenderTarget for RenderWindow {}
trait Drawable {
fn draw
I refer to Vladimir's excellent answer which explains Object's safety, however I am afraid than in the middle of the discussion the concrete problem at hand was forgotten.
As Vladimir mentions, the issue is that a method generic over types (generic over lifetimes is fine) renders the trait it belongs to unusable for run-time polymorphism; this, in Rust, is called Object Safety.
The simplest fix, therefore, is to remove the generic parameter of the method!
trait RenderTarget {}
struct RenderWindow;
impl RenderTarget for RenderWindow {}
trait Drawable {
fn draw(&self, target: &mut RenderTarget);
}
fn main() {
let mut win = RenderWindow;
let mut vec: Vec> = Vec::new();
for e in &vec {
e.draw(&mut win);
}
}
The main difference between:
fn draw(&self, target: &mut RT)
and
fn draw(&self, target: &mut RenderTarget)
is that the latter requires RenderTarget
to be Object Safe too as it is now used in a run-time polymorphism situation (so, no static method, no generic method, no Self
, ...).
Another (more technical) difference is that the former is "monorphised" at compile-time (that is RT
is substituted with the real type and all relevant optimizations applied) whereas the latter is not (and so, no such optimizations occur).