Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix 10-03: a wrong expression of lifetime annotations #3861

Closed
wants to merge 1 commit into from

Conversation

Arichy
Copy link

@Arichy Arichy commented Mar 14, 2024

I think it should be most instead of least in this case:

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

The following sentence says that

In practice, it means that the lifetime of the reference returned by the longest function is the same as the smaller of the lifetimes of the values referred to by the function arguments.

That's to say, the lifetime of returned reference is less than the smaller of the lifetimes of the two arguments. So, the lifetime of returned reference should be at most as long as 'a (<= 'a ✅), instead of at least (>= 'a ❎).

@Arichy Arichy changed the title fix: at least => at most Fix 10-03: a wrong expression of lifetime annotations Mar 14, 2024
Copy link
Contributor

@chriskrycho chriskrycho left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for opening this, but the text is correct! This one is tricky, though, because it is showing an interesting interaction between the different parts of the lifetime tracking system. In general, lifetime annotations do not set an upper bound on how long but a lower bound on the lifetime of the thing they are tracking. This is important: if it were the other way around, Rust would not be able to say much useful at all about the lifetimes used in return positions like this. After all, “at most” would include “no time at all”. What makes it a little tricky here is that Rust picks the shorter of the two input lifetimes because that is what makes its analysis safe: in the case where both x and y are given lifetime 'a, if x goes out of scope first then the return value from this function cannot safely live longer than x does—and the same with y. But Rust also has to know it has at least the same lifetime as x, or you couldn’t know when it was safe to use at all.

Tricky! But that’s the point of the example.

I will close this PR now accordingly, but hopefully that is clarifying.

@fubupc
Copy link

fubupc commented Aug 12, 2024

... lifetime annotations do not set an upper bound on how long but a lower bound on the lifetime of the thing they are tracking ...

So lifetime annotation like 'a is a lower bound of parameters and returned value. But it says nothing about how long 'a itself should be in this explanation:

The function signature now tells Rust that for some lifetime 'a, the function takes two parameters, both of which are string slices that live at least as long as lifetime 'a. The function signature also tells Rust that the string slice returned from the function will live at least as long as lifetime 'a.

Isn't it missing something like "Under this constraint, Rust will make 'a as large as possible"?

@chriskrycho
Copy link
Contributor

Just saw your follow-up. If we were trying to be an exhaustive reference, yes, we would add something like that, and get into the details, but that’s not what the book is trying to do. 😄 The text as is says enough to understand the constraint here!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants