Search code examples
rustsubtypingtrait-objects

Get Rc<RefCell<dyn T>>> on a sub-type


I have the following definitions:

trait A {
    fn f(&self);
}

trait B: A {
// ...
}

I'd like implement this kind of function:

fn convert(v: Rc<RefCell<dyn B>>) -> Rc<RefCell<dyn A>> {
}

I'd like to have a way for returning a value that share the same object, that's means that with these declarations:

let x: Rc<RefCell<dyn B>> /* = ... */;
let y = convert(Rc::clone(&x));

The calls x.f() and y.f() apply the call on the same object.

How can i implement the function convert or how can change the type definitions to have that behaviour and that kind of conversion (a conversion to a sub-object).


Solution

  • Thank for your ideas, i decided to use a compromise by avoiding the use of a trait-object as parameter of the function convert in according to Rust rules:

    use std::rc::Rc;
    use std::cell::RefCell;
    
    trait A {
        fn print(&self);
    }
    
    trait B: A {
    }
    
    trait Convert {
        fn convert(it: Rc<RefCell<Self>>) -> Rc<RefCell<dyn A>>;
    }
    
    struct MyType(u32);
    
    impl Convert for MyType {
        fn convert(it: Rc<RefCell<Self>>) -> Rc<RefCell<dyn A>> {it}
    }
    
    impl A for MyType {
        fn print(&self) {
            println!("MyType({}) as A", self.0);
        }
    }
    
    impl B for MyType {}
    
    fn main() {
        let a: Rc<RefCell<dyn A>>;
        {
            let b = Rc::new(RefCell::new(MyType(3)));
            a = Convert::convert(b.clone());
        }
    
        a.borrow().print();
    }
    

    Playground