0

Question

I usually use c++ lang, and recently I'm learning rust lang but now confusing the concept of lifetime.
My understanding for lifetime is as follows. Is this correct?

  • Lifetime is an attribute of instance.
  • Lifetime represents the valid scope of instance.

Background of above question

The following code is a sample code at here.

    {
        let r;                // ---------+-- 'a
                              //          |
        {                     //          |
            let x = 5;        // -+-- 'b  |
            r = &x;           //  |       |
        }                     // -+       |
                              //          |
        println!("r: {}", r); //          |
    }                         // ---------+

The document said that 'a is a lifetime, and 'b is also a lifetime.
but if my understanding is correct, 'a is not lifetime, just scope of symbol r... Is `a really lifetime?

P.S.

There are two things named "a lifetime": value's lifetime, and the lifetime attached to a reference.

Thank you! Maybe I understood a little bit more than before...

mng
  • 17
  • 4
  • 2
    *"Is `\`a` really a lifetime?"*. If you don't believe the official Rust book, which you are citing, what else will convince you? Or is your actual question something different? – Herohtar Apr 29 '22 at 03:00
  • _"'a is not lifetime, just scope of symbol r"_ What do you think is meant by "lifetime" if not "the part of the program's execution for which a value lives?" Or do you think that `r` is not a value and doesn't have a lifetime? (It does, it's a value of type `&i32` in this example.) – cdhowie Apr 29 '22 at 04:51
  • There are two things named "a lifetime": _value_'s lifetime, and the lifetime attached to a reference. The lifetime of the value is what the book is talking about, and it is semi-equal to the scope. The lifetime of the reference is the `'a` in `&'a i32`. Which one are you talking about? – Chayim Friedman Apr 29 '22 at 04:59

1 Answers1

3

A lifetime is not so much an attribute of an instance, it's more the opposite way around; when an instance is borrowed (a reference is taken), it is borrowed for a specific lifetime. The borrow checker will try to minimise the lifetime of the borrow so that it can be as permissive as possible whilst ensuring code is still safe.

Lifetimes are your way of communicating how long you need a reference to last to the compiler, and given that information, the compiler will check that nothing violates that rule (by holding the reference for longer), and that the reference is available for at least as long as you require it. This can be thought of in much the same way that a compiler can check type to ensure you don't assign a float to an integer.

Lifetimes are also independent of scope. Rust now has non-lexical lifetimes (https://github.com/rust-lang/rfcs/pull/2094 — see What are non-lexical lifetimes? for more detailed explanation), meaning that within a given scope, the borrow checker is capable of determining that borrows have shorter lifetimes than the containing scope.

Chayim Friedman
  • 47,971
  • 5
  • 48
  • 77
edb
  • 484
  • 3
  • 6
  • No. A borrow is a region, a lifetime is for variable. The fact that we attach a "lifetime" to a reference but what we describe is actually a (set of) regions contributes to the confusion. And NLL only makes lifetimes not strictly depend on **lexical** scope, but it is still based on semantic scope. – Chayim Friedman Apr 29 '22 at 04:37
  • [An alias-based formulation of the borrow checker (Polonius introduction)](https://smallcultfollowing.com/babysteps/blog/2018/04/27/an-alias-based-formulation-of-the-borrow-checker/); [NLL RFC](https://rust-lang.github.io/rfcs/2094-nll.html) – Chayim Friedman Apr 29 '22 at 04:43
  • @ChayimFriedman, the article you linked explicitly notes that it differs from the current NLL implementation, specifically that the meaning of `'a` changes from representing a "lifetime" to representing a "region" — it is a proposal for an alternative implementation, not the current implementation. From the NLL RFC, "whenever you create a borrow, the compiler assigns the resulting reference a lifetime", which to me seems like another way of stating "when an instance is borrowed (a reference is taken), it is borrowed for a specific lifetime" – edb May 02 '22 at 06:01
  • The NLL RFC also clarifies that a lifetime refers to "The lifetime of a reference, corresponding to the span of time in which that reference is used", not to "The lifetime of a value" (which is what I'm assuming you're referring to as "semantic scope", but please correct me if I've misinterpreted) – edb May 02 '22 at 06:04
  • I've read this article a long time ago so I may be misremembering, but while I took the name "region" from there, my emphasis wasn't on the name but on the fact that, like the OP thinks, instances _have_ lifetimes, and on their relationship to the lifetimes of the associated references. I really don't remember why I linked to the NLL RFC, but e.g. _remember_ seeing in some authoriative source while writing the above comment that the name "lifetime" also applies to value, but now I only see this in the NLL RFC as "everyday speech, not Rust glossary". I haven't digged deep, though. – Chayim Friedman May 02 '22 at 06:12
  • And yes, by "semantic scope" (a name I invented because I didn't rememeber how they call it) I mean value's lifetime. – Chayim Friedman May 02 '22 at 06:13