Why this code does work? [Solved]


#1
fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let L = "Hi there..!";

    {
        let W = "What the hell..?";
        println!("{}", longest(L, W));
    }
}

As you can see, in longest signature, i told rust that x and y have same life time.

But L and W don’t. Shoudn’t I get a compile error?
i get that there wont be a dangling reference. but if rust can deduct this why is there a need to specify life times?


#2

Technically, they both have the same lifetime in this case because their both static strings (and have the type &'static str). However, this would work even if they weren’t static strings:

fn longest<'a>(x: &'a str, y: &'a str) -> &'a str {
    if x.len() > y.len() { x } else { y }
}

fn main() {
    let l_owned = String::from("Hi there..!");
    let L: &str = &*l_owned;

    {
        let w_owned = String::from("What the hell..?");
        let W: &str = &*w_owned;
        println!("{}", longest(L, W));
    }
}

The reason is subtyping. The signature of longest states: “there exists a lifetime 'a such that &'a str is a subtype of both typeof(L) and typeof(W).” In other words, there exists a lifetime 'a = lifetimeof(L) ∩ lifetimeof(W).