Why is an output lifetime not elided to a single explicit lifetime?
Asked Answered
H

1

6

The Rust book provides the following code to illustrate a valid function definition where explicit lifetimes are required:

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

Later in that section, the authors introduce the rules of lifetime elision. The second rule of lifetime elision states that

if there is exactly one input lifetime parameter, that lifetime is assigned to all output lifetime parameters.

According this rule, the following function definition should be valid as well:

fn longest<'a>(x: &'a str, y: &'a str) -> &str {  // No explicit return lifetime
    // snip
}

Since longest has only one input lifetime parameter, the output lifetime parameter should be inferred as 'a. But this code fails to compile. The borrow checker provides the following help message:

help: this function's return type contains a borrowed value with an elided lifetime, but the lifetime cannot be derived from the arguments.

What does this mean and why can't the inferred lifetime be used in this case?

Hydrochloride answered 2/5 at 17:49 Comment(2)
The sentence you quote is in respect to lifetime elision, which does not apply with multiple input lifetime positions.Disloyal
Why though? Why couldn't the compiler infer the output lifetime if there is only one actual input lifetime?Hydrochloride
A
7

Interestingly, the Rust reference seems to suggest that your case should be supported. The article on lifetime elision says:

If there is exactly one lifetime used in the parameters (elided or not), that lifetime is assigned to all elided output lifetimes.

However, the Rustonomicon has slightly different phrasing. The article on lifetime elision there says (emphasis mine):

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

There is one lifetime used in the parameters, 'a, but there are two lifetime positions, one for each of the &strs. So it seems the nomicon is more accurately describing the rules of elision.

Apollonian answered 2/5 at 18:13 Comment(3)
Would you recommend filing an issue on the tracker for this? It looks like there's either a doc issue in the Reference, or a compiler issue with the current behavior (which, if fixed, should be accompanied by a change to the Nomicon).Narco
Interesting discrepancy. Why would it be that you couldn't infer the return lifetime from a function with multiple lifetime positions, even if the function was known in fact to have only one lifetime parameter?Hydrochloride
@Hydrochloride I'm unsure, though I would think its because an elided lifetime linking to an explicit lifetime would be confusing or unexpected.Apollonian

© 2022 - 2024 — McMap. All rights reserved.