Rust: Upcasting an Arc<dyn Trait> to an Arc<dyn Any>?

Suppose I have a trait object of type Asset, which is stored in an Arc, and I want to convert it to an Arc<dyn Any> to facilitate later downcasting.

Is there any safe way to do this? I have tried this (unsafe) strategy, but it seems to break the type information as I can’t downcast the resulting Arc<dyn Any> to its base type:

    let res: Box<dyn Asset> = thing_that_returns_dyn_asset();
    let res: Arc<dyn Asset> = Arc::from(res);

    // Unsafe: Cast an Arc<dyn Asset> to an Arc<dyn Any>.
    let res : Arc<dyn Any> = unsafe {
         Arc::from_raw(Arc::into_raw(res).as_any())
    };

But it does not seem to work. I’m aware that there’s a currently experimental feature to upcast objects, but that doesn’t seem to help.

>Solution :

The easiest way is to add a method that casts from Arc<Asset> to Arc<dyn Any>. Following as-any, we can do that in a custom trait and have a blanket implementation for it:

pub trait AsAnyArc {
    fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any>;
}

impl<T: 'static> AsAnyArc for T {
    fn as_any_arc(self: Arc<Self>) -> Arc<dyn Any> { self }
}

pub trait Asset: AsAnyArc { ... }

let res: Box<dyn Asset> = thing_that_returns_dyn_asset();
let res: Arc<dyn Asset> = Arc::from(res);

let res: Arc<dyn Any> = res.as_any_arc();

Leave a Reply