struct MyStruct {
my_field: SomeTypeThatImplementsDrop,
}
impl Drop for MyStruct {
fn drop(&mut self) {
// ...some destruction code here...
}
}
impl MyStruct {
// this method is called to signal to the object
// that it should not trigger some condition it
// would otherwise trigger when dropped.
pub fn alternate_destructor(self) {
// ...other destruction code here....
// the destruction code above has put self in such a
// state that self.drop() should not be run, but
// self.my_field.drop() should. Is the below code
// considered undefined behavior, and if so, how
// should I do it?
unsafe {std::ptr::drop_in_place(&mut self.my_field)};
std::mem::forget(self);
}
}
What would that look like? Is this sound?
impl MyStruct {
pub fn alternate_destructor(self) {
// ...alternate destruction code here...
let mut me = std::mem::ManuallyDrop::new(self);
unsafe {std::ptr::drop_in_place(&mut me.my_field as *mut _)};
}
}
This still leaves the problem of a mutable reference pointing to an invalid value, however briefly, after drop_in_place()
returns, right? Or is that not an issue once it gets coerced to a mutable pointer?
Yeah, it will look basically like that.
So long as you never use the &mut
again, you should be fine; creating it in place like you have is one way to help ensure that.