Is unsafe cast from Box<T> where T: Trait to Box<Trait> okay?

Hiya, is it safe to cast from Box<T> where T: Trait to Box<Trait>. My code is something like this:

type FnState<T> = SendBoxFnOnce<'static, (), Box<State<T>>>;

struct MyStruct {
    state_fns: Vec<FnState<T>>,
}

impl MyStruct {
    pub fn with_state<S, FnStateLocal>(mut self, state_fn: FnStateLocal) -> Self
    where
        S: State<T> + 'static,
        FnStateLocal: FnOnce() -> S + Send + Sync + 'static,
    {
        // FnOnce() -> Box<State<T>>
        // ::<'_, _, Box<(State<T> + 'static)>>
        let closure = move || {
            // Box up the state
            let boxed_state = Box::new((state_fn)());

            // Coerce it to a State<T> for type checker to be happy. Without this, it complains that
            // `closure` is a `Box<S>` instead of a `Box<State<T>>`, and won't be accepted by
            // `SendBoxFnOnce::from(F)`
            unsafe { Box::<State<T>>::from_raw(Box::into_raw(boxed_state)) }
        };
        self.state_fns.push(SendBoxFnOnce::from(closure));
        self
    }
}

sorry I haven’t made a minimal compilable example

In English:

  1. Take a function that returns an S where S: State, wrap it in a closure that returns Box<S>
  2. unsafely cast Box<S> to a Box<State>
  3. Wrap that as a closure, and create a SendBoxFnOnce from it

Step 2 is my concern, but I’m not sure where to go look besides here. It made the rustc compiler happy — I know that’s not a guarantee of correctness, but it does give it the appearance :upside_down_face:.

The unsafe cast is definitely not okay. There is no vtable coming from the raw data type.
A safe cast should work just fine. as Box<dyn State<T>>

1 Like

wow magic. I’m sure I tried this within my 100 attempts, but this works:

Box::new((state_fn)()) as Box<State<T>>

Thank you!