0

I've searched everywhere for this and found various answers for similar things but nothing specific yet.

Context: my networking subsystem is extendable with new message types. That rules out using an enum.

Is it valid to convert a Box<dyn Trait> to a Box<Concrete> using x_ptr as *const Box<Concrete> where x_ptr is an unsafe pointer to Trait?

If so what restrictions does it place on Concrete or Trait?

I looked at downcast() implementations for Any in the repo, and indeed it seems to just be casting between pointer types. So I assume what I am trying to do is indeed valid.

Full example below:

use std::rc::Rc;

trait A {
    fn name(&self) -> &str;
}

struct B {
    x: u32
}

impl B {
}

impl A for B {
    fn name(&self) -> &str {
        "hello"
    }
}

fn main() {
    let x: Rc<Box<dyn A>> = Rc::new(Box::new(B { x: 110 }));
    println!("count after creating x = {}", Rc::strong_count(&x));
    let x_ptr = Rc::into_raw(x.clone());
    println!("count after creating x = {}", Rc::strong_count(&x));
    
    let y = unsafe {
        // Convert back to an `Rc` to prevent leak.
        let x: Rc<Box<B>> = Rc::from_raw(x_ptr as *const Box<B>);
        println!("{}", x.x);
        println!("{}", x.name());
        x

        // Further calls to `Rc::from_raw(x_ptr)` would be memory-unsafe.
    };

    let z = y.clone();
    println!("count after creating x = {}", Rc::strong_count(&x));

    // The memory was freed when `x` went out of scope above, so `x_ptr` is now dangling!
}

Yields desired output of:

count after creating x = 1
count after creating x = 2
110
hello
count after creating x = 3
  • The dupe I've just added shows one way to fix the casting problem: just drop the inner `Box`. You can combine that with `as_any` to get a solution that's [entirely safe except for `from_raw`](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=82875a76ac06de34758059ac902f2b0d). – trent Mar 05 '21 at 16:31
  • oh damn, the Box is entirely uneccessary. Thank you sir! – Ignatio Mobius Mar 05 '21 at 19:11

0 Answers0