Search code examples
rustmove-semanticsownershipshadowing

What happens when you mutably shadow a Vector in Rust?


I'm currently working my way through the rustlings course and got confused when this exercise regarding move-semantics came up. Here is the gist of it:

fn main(){
  let vec0 = Vec::new();
  let mut vec1 = fill_vec(vec0);
  //stuff happens
}

fn fill_vec(vec: Vec<i32>) -> Vec<i32> {
  let mut vec = vec;
  //do stuff
  vec
}

From what I can tell, the immutable vec0 is being moved to fill_vec as parameter vec, which is then being mutably shadowed by let mut vec = vec;. Since Vectors are references to heap-storage, does this imply that a clone() takes place due to the shadowing, or is the same pointer reused and just made mutable? Why would shadowing be used in this case at all?


Solution

  • is the same pointer reused and just made mutable?

    Yes. Well the same object entirely, at runtime it's essentially a no-op.

    Why would shadowing be used in this case at all?

    Some people like the pattern of temporally "locking" and "unlocking" bindings via shadowing e.g.

    let a = …;
    …
    let mut a = a;
    // mutate `a` in-place
    let a = a; // lock to readonly again
    

    That's really just personal preference. Here:

    • A new variable could have been introduced but would it really have been more useful? What would it be called? vec_mut? Not like the source could be reused, it was moved from.
    • Alternatively, the input parameter could have been mut vec: … directly.

    That mostly comes down to personal choice.