How to do downcasting from trait to generic struct

#1
#[macro_use]
extern crate downcast_rs;
use downcast_rs::Downcast;
use std::fmt::Debug;

trait Base: Downcast {}
impl_downcast!(Base);

struct Foo<T: Debug>(T);
impl<T:Debug + 'static> Base for Foo<T> {}

fn run<T:Debug>(a: T) {
    println!("{:?}",a);
}

fn main() {
    let mut base: Box<Base> = Box::new(Foo(42));
    if let Some(foo) = base.downcast_ref::<Foo<_>>() {
        run(foo.0);
    } 
}

Is it possible to downcast a trait object to a generic struct like this? I am in a situation where I need to match the underlying concrete types with generic type parameters.

0 Likes

#2
base.downcast_ref::<Foo<_>>()
                        ^

You need to specify the exact type you’re downcasting to. I think that means the answer to your question is no, but I’m not exactly sure what you’re trying to do.

0 Likes

#3
#![deny(bare_trait_object)]  // eventually this will be the default

fn generic<T : Debug> (base: Box<dyn Base>)
{
    if let Some(foo) = base.downcast_ref::<Foo<T>>() {
        run(foo.0);
    } 
}

So you can feed a generic function’s type parameter into a downcast_ref, but if you really know nothing about what you have received besides some trait bound (e.g., Debug), maybe you can refactor your code into upcasting only Foo< Box<dyn Debug> > so that you get to be able to downcast to that “concrete”-ish type back.

0 Likes