Course contentsShow
← Rust
Lesson 341 of 1,9104. Lifetimes and Advanced OwnershipFree lesson

Reference Re-borrowing Dynamics

Differentiate between binding re-borrowing and explicit reference creation.

In this lesson, you will learn how Rust’s compiler automatically manages the lifecycle of references through a process called re-borrowing.

When you have a mutable reference (&mut T), you might wonder what happens when you pass it to a function or assign it to another variable. Rust uses a mechanism called re-borrowing to allow you to use that reference in new scopes without "moving" or consuming the original reference.

Implicit Re-borrowing

The magic of re-borrowing is that it is usually invisible. When you pass a &mut T to a function that expects a &mut T, the compiler effectively creates a new, shorter-lived reference that points to the same data.

Consider this example:

fn modify(val: &mut i32) {
    *val += 1;
}

fn main() {
    let mut number = 10;
    let ref1 = &mut number;

    // We pass ref1 to the function. 
    // The compiler "re-borrows" ref1 as a temporary &mut i32.
    modify(ref1); 

    // We can still use ref1 here because the re-borrow ended!
    println!("{}", ref1);
}

Binding Re-borrowing vs. Explicit Creation

In the code above, the re-borrow is binding-based; the compiler performs it automatically to satisfy the function signature. This is different from explicit reference creation, where you might manually write let ref2 = &mut *ref1;.

If you were to move the reference (for example, by passing it into a struct or a closure that takes ownership), the original ref1 would become unusable. Re-borrowing avoids this move by creating a temporary, nested loan. The compiler calculates that the new loan must end before the original ref1 can be used again.

Essentially, re-borrowing is the borrow checker saying: "I will grant a temporary sub-lease on this data, provided the original reference remains inactive until that sub-lease expires." This allows us to pass references around safely without losing control of the original pointer. It turns a potential ownership conflict into a temporary restriction, keeping your code both safe and ergonomic.

Key Takeaway: Re-borrowing allows you to pass mutable references into new scopes as temporary "sub-loans" without consuming the original reference, provided the sub-loan ends before the original is used again.