Search code examples
pointersrustcastingtraits

How to unsafely get a concrete reference from a Box<dyn Trait>?


I want to reference the specific struct in a Box<dyn Trait>. I know exactly what the struct is so I am ok with using unsafe operations. When I typecast it using raw pointers it gives a SIGSEGV.

trait Help {}

struct Me {
    data: Vec<String>
}

impl Help for Me {}

fn main() {
    let me = Me { data: vec!["please".to_string(), "help".to_string()] };
    let me: Box<dyn Help> = Box::new(me);
    
    let inner = unsafe {
        *(me.as_ref() as *const dyn Help as *const &Me)
    };
    dbg!(&inner.data);
    assert_eq!(inner.data, vec!["hello", "world"]);
}

Playground link

I'm trying to avoid Any because the production logic doesn't have it and I want to peek into the internal state for tests.


Solution

  • As I said in the comments, I believe it is a good idea to not do that with unsafe code, but if you really want, your mistake is the extra &:

    let inner = unsafe { &*(&*me as *const dyn Help as *const Me) };
    

    I also removed the as_ref() because it is risky, inference may turn it into things you didn't intend, and added a & in the beginning because it was required.