1

Consider the following code:

fn fun() {
    let mut vec = vec![];
    {
        let x: &[u8] = &[1, 2];
        vec.push(x); // why is the compiler happy?

        let y = [3, 4];
        let z: &[u8] = &y;
        vec.push(z); // ok compiler is not happy 
    }

    println!("{:?}", vec); // after commenting this line the compiler is happy again 
}

I understand why the compiler complains about "borrowed value does not live long enough" for y but why is it happy with x? x is a reference to a slice without a name -- when is this anonymous slice dropped and what is its lifetime?

After commenting the println everything compiles, I guess this is because the compiler understands that vec is not used anywhere so it does not care.

trent
  • 25,033
  • 7
  • 51
  • 90
Blezz
  • 313
  • 1
  • 10
  • What is the expected type of `vec`? I believe the compiler thinks it it `Vec<& 'static [u8; 2]>`. Try explicitly setting its type. – NovaDenizen Oct 17 '20 at 22:30

1 Answers1

3

In the case of x, the compiler reasons that &[1,2] is borrowing an expression that could be written in a constant, so it does constant promotion to &'static [u8; 2]:

Promotion of a value expression to a 'static slot occurs when the expression could be written in a constant, borrowed, and dereferencing that borrow where the expression was originally written, without changing the runtime behavior. That is, the promoted expression can be evaluated at compile-time and the resulting value does not contain interior mutability or destructors (these properties are determined based on the value where possible, e.g. &None always has the type &'static Option<_>, as it contains nothing disallowed).

The expression for z, which is &y, can not be written in a constant, because it is borrowing the variable y, so the same does not apply for z.

Frxstrem
  • 38,761
  • 9
  • 79
  • 119