Conversion Between Arc of dyn Trait

Hi All,

I'm having a problem working with trait objects and casting between them.

I'm working on some small 3D application using Vulkano. As a part of refactoring of certain prts of my project I'd like to create QoL traits and structures to better organize my code. Values given to me by Vulkano are often in the form of Arc<dyn TraitObject>, so i tried to implemet some trait on top of those provided by Vulkano. I've encounterd an issue converting between trait objects. (Code below is a minimal example of this issue)

use std::sync::Arc;

trait A {}

trait B : A {}

impl<ImplA: A> B for ImplA {}

struct Test;

impl A for Test{}

fn get_arc() -> Arc<dyn A> {
    Arc::new(Test)
}

fn main() {
    let arc_b : Arc<dyn B>;
    arc_b = get_arc().into();   // COMPILATION ERROR
}

You can cast trait objects to other trait objects. You'll need to put the conversion function in the trait. The best way to do this is with something like this:

https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=68bdcf826a6b57a4a56e3e4c0897596a

trait ToB {
    fn to_b<'a>(self: Arc<Self>) -> Arc<dyn B + 'a> where Self: 'a;
}

impl<T: B> ToB for T {
    fn to_b<'a>(self: Arc<Self>) -> Arc<dyn B + 'a> where Self: 'a { self }
}

trait A: ToB {}

Then you can do

get_arc().to_b()

I think there was a crate that codified this pattern, but I can't remember the name ...

3 Likes