1

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 Answers1

1

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.

kmdreko
  • 42,554
  • 6
  • 57
  • 106
  • In the link you gave, there is a suggestion about implementing ```as_any() -> &dyn Any``` on the trait, and it works. How is this different from my ```as &dyn Any``` ? And by getting back to the ```Box```, I'm back at the starting point. – LucioleMaléfique Sep 22 '22 at 08:39
  • @LucioleMaléfique The solution in the link is the only way to downcast into the original concrete type. When you do `&mut a as &mut dyn Any` you have already lost any association with the original concrete type. The `.as_any()` trick works because it *can* access the original type *through* the `dyn A` implementation. – kmdreko Sep 23 '22 at 00:16