Can't downcast from &mut Box<dyn Trait> as &mut dyn Any?

708 Views Asked by At

I encountered this issue, and I'm wondering why it doesn't work. I managed to replicate the problem :

I'm trying to get back to the struct from &mut Box<dyn Trait>, and this is my go at it:

use std::any::Any;

trait A {}

struct B;

impl A for B {}

fn main() {
    let mut a: Box<dyn A> = Box::new(B);
    let a_ref: &mut Box<dyn A> = &mut a;

    match (a_ref as &mut dyn Any).downcast_mut::<B>() { // downcast here 
        Some(_b) => println!("found b"),
        None => println!("found nothing")
    }
}

But this does not find the struct behind it ? Am I missing something ?

Here is a link to the playground

I've tried to downcast to other things, such as Box<B> or &mut B but none if this works.

1

There are 1 best solutions below

2
kmdreko On

You can't just say my_trait_object as &dyn Any and expect to be able to downcast to the original type. It does not work by magic, you need the original type to coerce itself as dyn Any, that's the only way it works. That is why the solutions here need to pass through the trait object, to get at the original type, to get it as an Any: How to get a reference to a concrete type from a trait object?

What happens here is that a concrete type is coerced into a dyn Any, but that concrete type is Box<dyn A>. This code prints "found box":

use std::any::Any;

trait A {}
struct B;
impl A for B {}

fn main() {
    let mut a: Box<dyn A> = Box::new(B);
    let a_ref: &mut Box<dyn A> = &mut a;

    match (a_ref as &mut dyn Any).downcast_mut::<Box<dyn A>>() {
        Some(_) => println!("found box"),
        None => println!("found nothing"),
    }
}

There's more explanation in the linked answers that I encourage you to read.