Course contentsShow
← Rust
Lesson 137 of 1,9102. The Ownership ModelFree lesson

Drop Order Dependencies

Control the sequence in which dependent objects are destroyed to prevent resource corruption.

In this lesson, you will learn how to manage the exact order in which objects are cleaned up to prevent your program from attempting to use resources that have already been destroyed.

The Rule of Reverse Construction

In Rust, when a scope ends, local variables are dropped in the reverse order of their declaration. If you define variable A and then variable B, Rust will drop B first, then A.

This matters immensely when A provides a service or a resource that B relies on. If B tries to "clean up" by talking to A during its own drop process, it must ensure A is still alive. If the order is wrong, your program might try to access a "use-after-free" resource, leading to crashes or data corruption.

A Concrete Illustration

Imagine you have a DatabaseConnection and a Transaction that uses that connection. The transaction cannot safely close itself if the connection is already gone.

struct Database { id: i32 }
struct Transaction { db_id: i32 }

impl Drop for Database {
    fn drop(&mut self) { println!("Closing DB: {}", self.id); }
}

impl Drop for Transaction {
    fn drop(&mut self) { println!("Committing transaction on DB: {}", self.db_id); }
}

fn main() {
    let db = Database { id: 1 };
    let tx = Transaction { db_id: db.id };
    // tx is dropped first, then db. This is safe.
}

Because tx was declared after db, it is dropped first. This is perfect: the transaction commits while the database connection is still valid.

What if the order is wrong?

If you manually need to control this (for example, if a wrapper needs to be dropped after its internal components), you can use std::mem::drop. Calling drop(variable) manually triggers the destructor early. This allows you to force a specific cleanup sequence before the end of the scope. By explicitly dropping dependencies in a specific order, you guarantee that no object ever attempts to interact with an "already-destroyed" component.

Key Takeaway: Rust drops variables in reverse declaration order; if your objects have complex dependencies, you must order their declarations carefully or use manual drop() calls to enforce a safe sequence.