Destructors - The Rust Reference

# Destructors

When an initialized variable in Rust goes out of scope or a temporary is no longer needed its destructor is run. Assignment also runs the destructor of its left-hand operand, unless it's an uninitialized variable. If a struct variable has been partially initialized, only its initialized fields are dropped.

The destructor of a type consists of

1. Calling its `std::ops::Drop::drop` method, if it has one.
2. Recursively running the destructor of all of its fields.
   - The fields of a struct, tuple or enum variant are dropped in declaration order. *
   - The elements of an array or owned slice are dropped from the first element to the last. *
   - The captured values of a closure are dropped in an unspecified order.
   - Trait objects run the destructor of the underlying type.
   - Other types don't result in any further drops.

* This order was stabilized in RFC 1857.

Variables are dropped in reverse order of declaration. Variables declared in the same pattern drop in an unspecified ordered.

If a destructor must be run manually, such as when implementing your own smart pointer, `std::ptr::drop_in_place` can be used.

Some examples:

    # #![allow(unused_variables)]
    #fn main() {
    struct ShowOnDrop(&'static str);

    impl Drop for ShowOnDrop {
        fn drop(&mut self) {
            println!("{}", self.0);
        }
    }

    {
        let mut overwritten = ShowOnDrop("Drops when overwritten");
        overwritten = ShowOnDrop("drops when scope ends");
    }
    # println!("");
    {
        let declared_first = ShowOnDrop("Dropped last");
        let declared_last = ShowOnDrop("Dropped first");
    }
    # println!("");
    {
        // Tuple elements drop in forwards order
        let tuple = (ShowOnDrop("Tuple first"), ShowOnDrop("Tuple second"));
    }
    # println!("");
    loop {
        // Tuple expression doesn't finish evaluating so temporaries drop in reverse order:
        let partial_tuple = (ShowOnDrop("Temp first"), ShowOnDrop("Temp second"), break);
    }
    # println!("");
    {
        let moved;
        // No destructor run on assignment.
        moved = ShowOnDrop("Drops when moved");
        // drops now, but is then uninitialized
        moved;
        let uninitialized: ShowOnDrop;
        // Only first element drops
        let mut partially_initialized: (ShowOnDrop, ShowOnDrop);
        partially_initialized.0 = ShowOnDrop("Partial tuple first");
    }
    #}

## Not running destructors

Not running destructors in Rust is safe even if it has a type that isn't `'static`. `std::mem::ManuallyDrop` provides a wrapper to prevent a variable or field from being dropped automatically.