Full context can be found in the github repository:
https://github.com/ljsnogard/snapshot-channel-rs/blob/dev/0.0.1/src/snapshot_.rs#L194
I store a future and its output into a union.
union FutOrOut<F>
where
F: Future,
{
future_: ManuallyDrop<F>,
output_: ManuallyDrop<F::Output>,
}
impl<F> FutOrOut<F>
where
F: Future,
{
pub unsafe fn pinned_future(self: Pin<&mut Self>) -> Pin<&mut F> {
let this = unsafe { self.get_unchecked_mut() };
unsafe { Pin::new_unchecked(this.future_.deref_mut()) }
}
pub unsafe fn output_ref(&self) -> &F::Output {
self.output_.deref()
}
pub unsafe fn output_mut(&mut self) -> &mut F::Output {
self.output_.deref_mut()
}
}
The state of FutOrOut is indicated by other bit flags.
Then, I have:
let mut fut_or_out: Pin<&mut FutOrOut<F>> = (*fut_guard).as_mut();
let fut: Pin<&mut F> = unsafe { fut_or_out.as_mut().pinned_future() };
// future polling here
let poll_res = fut.poll(cx);
let Poll::Ready(x) = poll_res
else {
// irrelevant
};
// future got overwrite here, is that sound?
unsafe {
let p = fut_or_out.get_unchecked_mut();
*(p.output_mut()) = x;
}
No crash encountered, but is that sound?