Lifetime of primitive types

I'm new to Rust. I would like to know the lifetime of &1 value in the below code snippet. Even though &1 is declared in the inner scope, it lives beyond that scope. Why &1 is not getting dropped once the inner scope ends? Looks like it has to do with primitive types, not sure what exactly is going on here.

rustc 1.60.0 (7737e0b5c 2022-04-04)

fn main() {
    let e;
    let y = 2;
    {
        e = Extreme::new(&1, &y);
    }
    println!("{:?}", e);
}

#[derive(Debug)]
struct Extreme<'a, T> {
    min: &'a T,
    max: &'a T,
}

impl<'a, T> Extreme<'a, T> {
    pub fn new(min: &'a T, max: &'a T) -> Self {
        Self { min, max }
    }
}

If I change from i32 to String, it works as expected.

temporary value dropped while borrowed
consider using a `let` binding to create a longer lived

This is not because &1 is a primitive. This is because static promotion. &1 is being rewritten like:

{
    static V: i32 = 1;
    &V
}

And thus has the 'static lifetime.

4 Likes

I'm guessing you tried something like

fn main() {
    let e;
    let y = String::new();
    {
        e = Extreme::new(&String::new(), &y);
    }
    println!("{:?}", e);
}

Note that it's the String created in the inner block that is problematic, not the reference. You can create a reference in the inner block, store it in e, and have it be valid beyond the block -- provided it is referencing something that is also valid beyond the block. The lifetime of a reference is not limited to the block in which it is created.

Thus, this works.

fn main() {
    let e;
    let y = String::new();
    {
        e = Extreme::new(&y, &y);
    }
    println!("{:?}", e);
}

And this doesn't (the local variable prevents static promotion).

fn main() {
    let e;
    let y = 2;
    {
        let x = 1;
        e = Extreme::new(&x, &y);
    }
    println!("{:?}", e);
}
3 Likes

Thank you.

Thank you..