Search code examples
vectorrustmutable

Rust mutability of nested data structures


Can anyone explain why the following code will compile, but if I comment out one line then it does not, even though the code is essentially doing the same thing?

struct OtherStruct {
  x: i32,
}

struct Inner {
  blah: i32,
  vector: Vec<OtherStruct>
}

struct Outer {
  inner: Inner,
}

impl Inner {
  pub fn set_blah(&mut self, new_val : i32) {
    self.blah = new_val;
  }
}

fn main() {
  let mut outer = Outer {
    inner: Inner {
      blah: 10,
      vector: vec![
        OtherStruct { x: 1 },
        OtherStruct { x: 2 },
        OtherStruct { x: 3 },
        OtherStruct { x: 4 },
        OtherStruct { x: 5 },
      ]
    }
  };

  for item in outer.inner.vector.iter() {
    println!("{}", item.x);
    outer.inner.blah = 4;
    //outer.inner.set_blah(6);
  }

}

The compiler error is:

   |
34 |   for item in outer.inner.vector.iter() {
   |               -------------------------
   |               |
   |               immutable borrow occurs here
   |               immutable borrow later used here
...
37 |     outer.inner.set_blah(6);
   |     ^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here

Which makes sense to me, I guess I'm wondering why I'm allowed to get away with it when I don't use a function call, surely the same mutability issues arise?


Solution

  • set_blah needs to borrow the entire Inner struct object. The assignment to blah only needs to borrow the field itself, which works because it has not been borrowed yet.