0

In this question:

How to get a reference to a concrete type from a trait object?

Explains how to use Any to downcast a Trait. But I would like to downcast directly from the Trait to all the supported known types instead of using a generic as_any method. I tried:

pub trait A{
    fn as_B(&self) -> B {
        (&self as &dyn Any).downcast_ref::<B>().expect("Can't cast to B").clone()
    }
}
impl A for B{}

But I get the error: lifetime may not live long enough cast requires that '1 must outlive 'static

I have tried:

  1. Mark trait A as Clone, but this is not an option since this break other Traits that uses A and need those traits to be object traits.
  2. Put life time parameters in the trait. This litter a lot of places where my trait A is used and in the end I get the same compilation error.
  3. Remove & from self. But is neither an option since A size is not known.
rsan
  • 1,887
  • 2
  • 17
  • 23

1 Answers1

-2

Edited:

If you just want what Any does without going through it here rust playground, this is UB since Any is meant to translate to usable type,

trait A{
    // Edited from std::any::Any downcast_ref_unchecked there is a checked version if you want to look
    fn downcast_ref_unchecked(&self) -> &B where Self: Sized{
            // Don't ask me how this works but I believe it dips into C land of pointers
            unsafe { &*(self as *const dyn A as *const B) }
    }
}
// Target
#[derive(Debug)]
struct B;

// Test
#[derive(Debug)]
struct C;

// Have test struct have 'A' trait
impl A for C {}

fn main(){
    let t = C{};
    println!("{:?}", t.downcast_ref_unchecked());
    println!("{:?}", t);
}
Rdna123
  • 7
  • 2
  • 1
    This answer is UB, unless either `B` is the only implementor (i.e. the downcast is always correct) or `B` is zero-sized (i.e. there are no fields to be accessed from reference to it). – Cerberus Feb 14 '23 at 06:03
  • @rsan It was downvotes probably because it is terribly unsound. There is a reason std's `downcast_unchecked()` is marked unsafe. – Chayim Friedman Feb 14 '23 at 06:48
  • What they are asking for is UB already, since Any just allows anything to be a argument in a function, and downcast functions are meant to turn the Any to appropriate type for use. – Rdna123 Feb 15 '23 at 04:51