Course contentsShow
← Rust
Lesson 35 of 1,9101. Rust Fundamentals and ToolingFree lesson

Preventing Use-After-Move Errors

Debug and resolve ownership errors by understanding the scope of variable bindings.

In this lesson, you will learn how to identify and resolve "use-after-move" errors by understanding how Rust’s compiler tracks variable validity after ownership is transferred.

Understanding the "Use-After-Move" Error

In Rust, when you assign one variable to another (like moving a String or a Box), the original variable is no longer considered valid. If you try to use it afterward, the compiler halts the process. This is the "use-after-move" error. It exists to ensure memory safety—preventing two variables from owning and potentially "cleaning up" the same heap-allocated data at the same time.

The Anatomy of the Error

Consider this simple function:

fn main() {
    let name = String::from("Rust");
    let owner = name; // 'name' is moved to 'owner'

    println!("{}", name); // ERROR: borrow of moved value: `name`
}

When owner = name executes, Rust updates its internal tracking: name no longer owns the heap memory. The variable name is now "uninitialized" in the eyes of the compiler. When you try to print name, the borrow checker sees that the binding has been moved and flags an error.

How to Prevent These Errors

To resolve these errors, you have three primary strategies based on what you need to achieve:

  1. Clone the Data: If you truly need two copies of the data, use the .clone() method. This performs a "deep copy," creating a new allocation on the heap so both variables remain valid.

    let owner = name.clone(); // Both 'name' and 'owner' are now valid
    
  2. Borrow Instead of Move: If you only need to read the data, use a reference (&). References don't take ownership, meaning the original variable remains the owner.

    let reference = &name; // 'name' is still the owner
    println!("{}", name);  // This works fine now!
    
  3. Re-assignment: If you are finished with the first variable, simply accept the move and avoid using the old variable name. If you need to use the variable again, ensure you re-initialize it before usage.

Key Takeaway: A moved variable is effectively "empty" to the compiler; to keep using it, you must either borrow it with & or explicitly duplicate it with .clone().