2

I'm learning Rust from the official book. Concerning Rc, it has the following section:

We could change the definition of Cons to hold references instead, but then we would have to specify lifetime parameters. By specifying lifetime parameters, we would be specifying that every element in the list will live at least as long as the entire list. The borrow checker wouldn’t let us compile let a = Cons(10, &Nil); for example, because the temporary Nil value would be dropped before a could take a reference to it.

I implement this with the following code, and it can compile and run:

#[derive(Debug)]
enum List2<'a> {
    Cons(i32, &'a List2<'a>),
    Nil,
}

use crate::List2::{Cons, Nil};

fn main() {
    let x = Cons(1, &Nil);
    let y = Cons(2, &x);
    let z = Cons(3, &x);

    println!("{:?}", y);
    println!("{:?}", z);
}

result:

Cons(2, Cons(1, Nil))
Cons(3, Cons(1, Nil))

Is my implementation has some problems or the official docs is out of date?

Konrad Rudolph
  • 530,221
  • 131
  • 937
  • 1,214
  • @E_net4thecurator While this answer the question, this is not what happens here technically - this is a static promotion and the linked question is about scope lifetime extension (not that it matters in this case). – Chayim Friedman Jan 05 '22 at 10:50
  • `'static` promotion explains why `Cons (1, &Nil)` works, it doesn't explain why `Cons (2, &x)` works since `x` is a `List2<'static>` but `&x` doesn't have a `'static` lifetime -> so what lifetime is `'a` for `y`? – Jmb Jan 05 '22 at 11:04
  • Why do you think `x` is `List2<'static>`? Anyway, the question was about `Cons(10, &Nil)`. – Chayim Friedman Jan 05 '22 at 11:25
  • @ChayimFriedman I think `x` is `List2<'static>` because `&Nil` is `'static` and because the [playground](https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=53fe4850cd5f6d8adc105512e5074d50) concurs. – Jmb Jan 05 '22 at 13:14
  • @Jmb This declaration alone definitely _can_ be `'static`, but there are other declarations, and _together_ they form the lifetime `'a`. – Chayim Friedman Jan 05 '22 at 13:46
  • @ChayimFriedman In fact `x`, `y` and `z` each have a _different_ lifetime `'a`. Thanks to [subtyping](https://doc.rust-lang.org/reference/subtyping.html) and because `List2<'a>` is covariant in `'a` you can put a `List2` with a given lifetime `'a` inside a `List2` with a _different_ lifetime `'a` provided the second lifetime is smaller than the first. – Jmb Jan 05 '22 at 14:22

0 Answers0