2

Minimum code:

fn foo() {
    let vector = vec![1u8, 2u8];
    let a = &vector.as_slice()[0];
    drop(vector);
    let b = a;
}

fn bar() {
    let array = [1u8, 2u8];
    let a = &array[0];
    drop(array);
    let b = a;
}

When compiling the above codes, foo can't compile while bar can.

In function foo, a borrows the vector, so after I drop vector, I can't access a any more.

However, I think the situation is same for bar, but bar can successfully pass the compilation. I don't know why.

Evian
  • 1,035
  • 1
  • 9
  • 22

2 Answers2

3

This is not specific to vectors and arrays. As soon as Rust can prove that a value is a constant known at compile time, it considers it has having a static lifetime (and drop in this case doesn't have any effect since the value will last forever). See this similar question.

I extended your example with a simple constant put in a variable (binding) and a boxed version; this shows the exact same distinction as you noticed between vector and array (trivial constant vs dynamically allocated value).

fn test_vec() {
    let src = vec![10u8, 20u8];
    let a = &src[0];
    // drop(src); // rejected by compiler
    let b = a;
    println!("{:?}", b);
}

fn test_array() {
    let src = [10u8, 20u8];
    let a = &src[0];
    drop(src);
    let b = a;
    println!("{:?}", b);
}

fn test_box() {
    let src = Box::new(10u8);
    let a = &src;
    // drop(src); // rejected by compiler
    let b = a;
    println!("{:?}", b);
}

fn test_var() {
    let src = 10u8;
    let a = &src;
    drop(src);
    let b = a;
    println!("{:?}", b);
}

fn main() {
    test_vec();
    test_array();
    test_box();
    test_var();
}
prog-fh
  • 13,492
  • 1
  • 15
  • 30
2

An immutable array literal has static lifetime. Dropping the local variable array doesn't really do anything in this case – the data is mapped into memory when the binary is loaded, and it will stay there for the runtime of the program, so the reference is still vaild. You just can't access the memory via the array variable anymore.

The vector case is very different. Creating a new vector dynamically allocates memory on the heap at runtime, and drop() will release that memory again, so the reference becomes invalid.

Sven Marnach
  • 574,206
  • 118
  • 941
  • 841