Which side is handling lifetime specifier in rust compiler?

Lifetime annotations guide the borrow checker. Consider the following function (which does not compile, because the borrow checker cannot work out what I mean):

use std::str::FromStr;

fn choose_a_string(which_one: &str, str1: &str, str2: &str) -> &str {
    let choice = bool::from_str(which_one).unwrap_or_else(|_| {
        let num = i32::from_str(which_one).unwrap_or(0);
        num == 0
    });
    if choice {
        str1
    } else {
        str2
    }
}

Without lifetime annotations, it's unclear to the borrow checker what constraints apply to the lifetimes of the references. By adding lifetime annotations, I can make it clear:

fn choose_a_string<'retval>(
    which_one: &'_ str,
    str1: &'retval str,
    str2: &'retval str,
) -> &'retval str {

(Rust Playground with lifetime annotations).

With the added annotations, the borrow checker can see that which_one's lifetime is unrelated to the lifetime of the return value, and that both str1 and str2 need to be valid while the return value is alive.

8 Likes