1

Since Rust doesn't support upcasting, I'm trying to do the as_any trick mentioned here, but with a parameterized type. However, when I try to call downcast_ref on the returned Any, I get None. Since I cannot print Any to find out what it actually is:

`dyn std::any::Any` doesn't implement `std::fmt::Display`

`dyn std::any::Any` cannot be formatted with the default formatter

How can I debug what it actually is? Here is the failing code (playground):

use std::any::Any;
use std::rc::{Rc, Weak};

pub trait Wrapper: Any {
    fn as_any(&self) -> &dyn Any;
}

pub struct WeakWrapper<T: Any> {
    item: Weak<T>,
}

impl<'a, T: Any + 'static> Wrapper for WeakWrapper<T> {
    fn as_any(&self) -> &dyn Any {
        self
    }
}

fn main() {
    let rc = Rc::new(Box::new(5));
    let weak_wrapper = WeakWrapper {
        item: Rc::downgrade(&rc),
    };
    let item = weak_wrapper
        .as_any()
        .downcast_ref::<WeakWrapper<i32>>()
        .map(|w| w.item.upgrade().map(|n| *n))
        .flatten();
    println!("Item is {}", item.unwrap());
}
trent
  • 25,033
  • 7
  • 51
  • 90
wrongusername
  • 18,564
  • 40
  • 130
  • 214

1 Answers1

3

That's because you're downcasting to the wrong type: you're trying to downcast to WeakWrapper<i32> but weak_wrapper is a WeakWrapper<Box<i32>>: https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=f49a3c2236beabae48a41d024a04d08f

Since I cannot print Any to find out what it actually is

You can debug-print the TypeId, though it's not very helpful (you get a pretty opaque number) it can be compared to TypeId::of::<type>(), so you can do e.g.

any_value.type_id() == TypeId::of::<WeakWrapper<i32>>()

and find out that it's false, but

any_value.type_id() == TypeId::of::<WeakWrapper<Box<i32>>>()

is true.

Masklinn
  • 34,759
  • 3
  • 38
  • 57