lets take for example this piece of code.
trait Thingy {
fn func1(self: &Rc<Self>);
}
struct ImplementThingy{}
impl Thingy for ImplementThingy {
fn func1(self: &Rc<Self>) {
println!("ImplementThingy func1!");
}
}
fn main() {
let hello = Rc::new(ImplementThingy {});
hello.func1();
}
This prints the ImplementThingy
thingy.
However when I add
struct HasPointer {
member:Rc<dyn Thingy>
}
impl HasPointer {
fn new(x: u32) -> HasPointer {
let member: Rc<dyn Thingy> = if x > 10 {
Rc::new(ImplementThingy {})
} else {
Rc::new(ImplementThingy2 {})
};
return Self {
member
};
}
}
The code does not compile anymore:
Compiling playground v0.0.1 (/playground)
error[E0038]: the trait `Thingy` cannot be made into an object
--> src/main.rs:4:15
|
4 | member:Rc<dyn Thingy>
| ^^^^^^^^^^ `Thingy` cannot be made into an object
...
24 | fn func1(self: &Rc<Self>);
| --------- help: consider changing method `func1`'s `self` parameter to be `&self`: `&Self`
|
note: for a trait to be "object safe" it needs to allow building a vtable to allow the call to be resolvable dynamically; for more information visit <https://doc.rust-lang.org/reference/items/traits.html#object-safety>
--> src/main.rs:24:20
|
23 | trait Thingy {
| ------ this trait cannot be made into an object...
24 | fn func1(self: &Rc<Self>);
| ^^^^^^^^^ ...because method `func1`'s `self` parameter cannot be dispatched on
For more information about this error, try `rustc --explain E0038`.
error: could not compile `playground` (bin "playground") due to previous error
and to make both pieces of code work I need to remove the &
from the fn func1(self: &Rc<Self>)
.
I was wondering if there's a way that
fn main() {
let hello = Rc::new(ImplementThingy {});
hello.func1();
let x = HasPointer::new(7);
x.member.func1();
x.member.func1();
}
would work.
I don't understand why adding that dyn rc member causes the code to stop working.