I have originally asked this question here, but it was marked as duplicate, although it duplicates only a part of it in my opinion, so I have created a more specific one:
Consider the following code:
use std::rc::Rc;
trait MyTrait {
fn trait_func(&self);
}
struct MyStruct1;
impl MyStruct1 {
fn my_fn(&self) {
// do something
}
}
impl MyTrait for MyStruct1 {
fn trait_func(&self) {
// do something
}
}
fn my_trait_fn(t: Rc<dyn MyTrait>) {
t.trait_func();
}
fn main() {
let my_str: Rc<MyStruct1> = Rc::new(MyStruct1);
my_trait_fn(my_str.clone());
my_str.my_fn();
}
This code works fine. Now I want to change the definition of trait_func
to accept a &mut self
, but it won't work as Rc
works with immutable data only. The solution I use is to wrap MyTrait
into RefCell
:
use std::cell::RefCell;
fn my_trait_fn(t: Rc<RefCell<Box<dyn MyTrait>>>) {
t.borrow_mut().trait_func();
}
fn main() {
let my_str: Rc<RefCell<Box<MyStruct1>>> = Rc::new(RefCell::new(Box::new(MyStruct1)));
my_trait_fn(my_str.clone());
my_str.my_fn();
}
When I compile it I get an error:
error[E0308]: mismatched types
--> src/main.rs:27:17
|
27 | my_trait_fn(my_str.clone());
| ^^^^^^^^^^^^^^ expected trait MyTrait, found struct `MyStruct1`
|
= note: expected type `std::rc::Rc<std::cell::RefCell<std::boxed::Box<dyn MyTrait + 'static>>>`
found type `std::rc::Rc<std::cell::RefCell<std::boxed::Box<MyStruct1>>>`
= help: here are some functions which might fulfill your needs:
- .into_inner()
What's the best way to go around this problem?
Rc<MyTrait>
, your second code uses an additionalBox
which is only necessary on stable. Without theBox
your code works fine on nightly with just some minor modifications: is.gd/zQUJqp . Please edit your question if you want a solution for stable rust. – HydrolyseBox
seems to be the solution to my problem. I think the ability forRefCell
to work directly with Trait was introduced recently that's why it wasn't working for me originally (when I updated my nightly Rust about 2 weeks ago). – Acceleration