Lifetime Elision - The Rustonomicon
Description: The Dark Arts of Advanced and Unsafe Rust Programming

# Lifetime Elision

In order to make common patterns more ergonomic, Rust allows lifetimes to be elided in function signatures.

A lifetime position is anywhere you can write a lifetime in a type:

    &'a T
    &'a mut T
    T<'a>

Lifetime positions can appear as either "input" or "output":

- For `fn` definitions, input refers to the types of the formal arguments in the `fn` definition, while output refers to result types. So `fn foo(s: &str) -> (&str, &str)` has elided one lifetime in input position and two lifetimes in output position. Note that the input positions of a `fn` method definition do not include the lifetimes that occur in the method's `impl` header (nor lifetimes that occur in the trait header, for a default method).

- In the future, it should be possible to elide `impl` headers in the same manner.

Elision rules are as follows:

- Each elided lifetime in input position becomes a distinct lifetime parameter.

- If there is exactly one input lifetime position (elided or not), that lifetime is assigned to all elided output lifetimes.

- If there are multiple input lifetime positions, but one of them is `&self` or `&mut self`, the lifetime of `self` is assigned to all elided output lifetimes.

- Otherwise, it is an error to elide an output lifetime.

Examples:

    fn print(s: &str);                                      // elided
    fn print<'a>(s: &'a str);                               // expanded

    fn debug(lvl: usize, s: &str);                          // elided
    fn debug<'a>(lvl: usize, s: &'a str);                   // expanded

    fn substr(s: &str, until: usize) -> &str;               // elided
    fn substr<'a>(s: &'a str, until: usize) -> &'a str;     // expanded

    fn get_str() -> &str;                                   // ILLEGAL

    fn frob(s: &str, t: &str) -> &str;                      // ILLEGAL

    fn get_mut(&mut self) -> &mut T;                        // elided
    fn get_mut<'a>(&'a mut self) -> &'a mut T;              // expanded

    fn args<T: ToCStr>(&mut self, args: &[T]) -> &mut Command                  // elided
    fn args<'a, 'b, T: ToCStr>(&'a mut self, args: &'b [T]) -> &'a mut Command // expanded

    fn new(buf: &mut [u8]) -> BufWriter;                    // elided
    fn new<'a>(buf: &'a mut [u8]) -> BufWriter<'a>          // expanded