calling_drop/
calling_drop.rs

1use replace_drop::{ReplaceDrop, ReplaceDropImpl};
2
3struct Inner;
4
5impl Drop for Inner {
6    fn drop(&mut self) {
7        println!("Inner!");
8    }
9}
10
11struct Outer(Inner);
12
13impl Drop for Outer {
14    fn drop(&mut self) {
15        println!("Outer!");
16    }
17}
18
19unsafe impl ReplaceDropImpl for Inner {
20    unsafe fn drop(&mut self) {
21        println!("Inner 2!");
22    }
23}
24
25unsafe impl ReplaceDropImpl for Outer {
26    unsafe fn drop(&mut self) {
27        println!("Outer 2!");
28
29        // The constructor for the fields wont automatically run, so you have to use drop_in_place to call it
30
31        // NOTE: you cant use std::mem::drop(self.0) because that requires ownership (we only have a mut ref)
32        // SAFETY: A mut reference is always a valid pointer
33        std::ptr::drop_in_place(&mut self.0 as *mut _);
34
35        // You can also call a ReplaceDropImpl directly
36        ReplaceDropImpl::drop(&mut self.0);
37
38        // Calling drop on self
39        std::ptr::drop_in_place(self as *mut _);
40    }
41}
42
43fn main() {
44    let _ = ReplaceDrop::new(Outer(Inner));
45    // Prints:
46    // Outer 2!
47    // Inner!
48    // Inner 2!
49    // Outer!
50    // Inner!
51}