What should the code of changing the definition of Cons to hold references look like?

This article is about "the Reference Counted Smart Pointer".

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.

What should the code look like?

I wrote a code like this:

enum List<'a> {
    Cons(i32, &'a List<'a>),

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

fn main() {
    let a = Cons(10, &Cons(4, &Nil));
    let mut c = &a;
    loop {
        match c {
            Cons(x, l) => {
                println!("item {}", x);
                c = l;
            Nil => {

I can't understand the last sentence of the paragraph. It seems that the compiler doesn't report any error.

It was written a while ago before updates to lifetime analysis. In this case the term to look for is static promotion.

Note using lifetimes does limit what you can do, for example it's difficult to build a list dynamically (i.e. from user input).

Edit: the part about &Nil was written a while ago, before static promotion landed, and the book wasn't updated to account for this. It should be updated.

1 Like

Sorry, could you say more about your first part? I'm a new rust player...
(cheers the same avatar :rofl:

1 Like

Static promotion means that let a = Cons(10, &Cons(4, &Nil)); is compiled to this:

static GLOBAL_1 = Nil;
static GLOBAL_2 = Cons(4, &GLOBAL_1);

let a = Cons(10, &GLOBAL_2);

When the article you are looking at was written, this didn't happen, and the two globals were local variables instead. This could cause issues because once the local variables are destroyed, the references to them are no longer usable.