Let's say I've got a struct that contains a pinned pointer to a boxed T and is Drop:
struct S<T> {
t: Pin<Box<T>>,
}
impl<T> Drop for S<T> {
// ...
}
How do I implement the following function without needing to add an otherwise-unnecessary Option layer? Unsafe code is fine.
impl<T> S<T> {
/// Release the handle to the `T` object, consuming the struct so it
/// isn't dropped.
fn into_t(self) -> Pin<Box<T>> {
todo!();
}
}
The basic challenge is that Pin<Box<T>> has no "missing" representation so can't directly be taken. I can think of ways to do it with ManuallyDrop and type punning, but I'm not 100% sure that the type punning is guaranteed to be okay. I'm looking for either an API that does this directly, or citations for memory layout that say it's okay to do whatever tricks the answer contains.
SisDrop. Thanks, will clarify in the question.ManuallyDroplike this: stackoverflow.com/a/74914046/2189130 I'm not sure what you mean by type punningManuallyDrop. The type punning would be something like creating a localManuallyDrop<S>, then using a pointer cast to access that as aManuallyDrop<Pin<Box<T>>, andtakefrom that.ManuallyDropdoesn't require type punning, it's perfectly fine to useManuallyDrop<Pin<Box<T>>: play.rust-lang.org/… (Not posting this as answer, because jacobsa's approach results in the same effect, but with much less code, unless you're scared bystd::ptr::read().)