Downgrade Arc<Box<impl Trait>> to Weak<Box<dyn Trait>>

Hi,
I have a problem to downgrade Arc<Box> to Weak<Box>. My code looks like this:

fn to_weak(t: &Arc<Box<impl Trait>>) -> Weak<Box<dyn Trait>> {
    Arc::downgrade(t) as Weak<Box<dyn Trait>>
}

what I get from the compiler is a non-primitive cast error. It is noted that I should implement the ‘From’ trait but I would do the same in the trait impl.
What is the right syntax for that?

Some explanation what I want to do
I have some threads that update the impl Traits when they are done updating, they send messages to following threads which update their own state based on the updated impl Traits. Therefore I want the depending threads to hold weak references to both get the updates and recognize if a thread crashed (= impl Trait was dropped). In addition I have a pool of weak references where a new thread get its dependencies on creation.

Without the box you can;

fn to_weak(t: &Arc<impl Trait + 'static>) -> Weak<dyn Trait> {
    Arc::downgrade(&(t.clone() as Arc<dyn Trait>))
}
2 Likes

Thank you for your quick response.

Can you explain why the 'static lifetime is needed? And if it can be omitted?

Further on I want to store that weak references in a pool, i.e. a Vec. I thought it was neccessary to put the trait object into a Box in that case.

'static is needed because Weak<dyn Trait> is really Weak<dyn Trait + 'static> due to default object bounds.

If you wanted to allow an arbitrary lifetime bound:

fn to_weak<'a>(t: &Arc<impl Trait + 'a>) -> Weak<dyn Trait + 'a> {
    Arc::downgrade(t) as _
}

You don’t need to always use Box for storing trait objects - the other smart pointer types like Rc, Arc, Weak also allow it. Whether to use Box or the others is a choice around desired ownership semantics over the trait object.

2 Likes