Why Doesn’t Rust Automatically Use the Shortest Lifetime for Multiple References?

In Rust, when a function has multiple reference parameters, explicit lifetime annotations are required if the return type is a reference. I understand that Rust uses lifetime elision rules in simple cases, but when there are multiple lifetimes, why doesn’t Rust automatically infer the shortest one?

For example, in this function:

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

Why does Rust require the explicit 'a annotation instead of assuming the shortest lifetime by default? Wouldn’t choosing the shortest lifetime always be the safest approach?

In contrast, this function compiles without explicit lifetimes:

fn example(x: &str) -> &str {
    x // ✅ This compiles! Rust infers the same lifetime.
}

Why does Rust allow lifetime elision in example but not in longest? I'd love to understand the reasoning behind this.

Lifetime elision works by using the first lifetime given in the arguments. For example:

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

// is equivalent to

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

This behavior is especially useful for functions that take &(mut) self, as usually the returned value only references self.

1 Like

This is only when this first lifetime is on &[mut] self, otherwise elision doesn't do anything.

5 Likes

There is no intrinsically shorter lifetime here.

But I'm afraid I don't know your mental model of lifetimes, or how you wish elision did act, well enough to make this comment constructive or elucidating.

1 Like

This recent thread on IRLO covered this topic:

3 Likes

This completely clears up my doubt. Thank you so much, @Kyllingene!

I thought:-

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

// is equivalent to

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

That's why I was getting confused.

Was it intentional that you didn't use 'b or was that a mistake?