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:
- Take a function that returns an
S where S: State
, wrap it in a closure that returnsBox<S>
-
unsafe
ly castBox<S>
to aBox<State>
- 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 .