Course contentsShow
← Rust
Lesson 239 of 1,9103. Borrowing and ReferencesFree lesson

Lifetime Subtyping

Understand how one lifetime can be a subtype of another based on inclusion.

In this lesson, you will learn how one lifetime can act as a "subtype" of another, allowing you to use a reference in places that are more restrictive than its original scope.

The Concept of Inclusion

In Rust, we often think of lifetimes as rigid constraints. However, there is a natural hierarchy based on how long a reference is valid. If a reference lives for 'long, and another lives for 'short, where 'long completely contains the duration of 'short, we say that 'long is a subtype of 'short.

In technical terms, if 'long : 'short (read as: "'long outlives 'short"), you can treat the longer-lived reference as if it were the shorter one. This is beneficial because the compiler allows you to "downgrade" a long-lived reference to satisfy a function or struct that expects a shorter duration.

A Concrete Illustration

Imagine you have a function that requires a reference to a string. If you provide a reference that lives for the entire duration of your program (like a 'static string), it will be accepted by any function, regardless of how short the expected lifetime is.

fn print_message(msg: &str) {
    println!("{}", msg);
}

fn main() {
    let long_lived = "I live forever!"; // This has a 'static lifetime
    
    // Even though print_message expects a regular &str, 
    // it accepts our 'static reference because 'static 
    // is a subtype of any other lifetime.
    print_message(long_lived);
}

Because the long_lived reference exists for the entire program, it "includes" the duration of any local scope. The Rust compiler treats this inclusion as subtyping: since your reference is valid for at least as long as the function needs it, the subtyping relationship allows the borrow checker to remain satisfied.

You don’t have to manually declare these relationships most of the time; the compiler automatically identifies when a reference has a longer scope than the one required by the signature and applies this subtyping logic under the hood to keep your code flexible and safe.

Key Takeaway: If a lifetime 'a covers a longer duration than 'b, you can use 'a wherever 'b is expected because 'a is a subtype of 'b.