Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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?

like image 349
Richard Howell-Peak Avatar asked Sep 07 '20 04:09

Richard Howell-Peak


1 Answers

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.

like image 143
Florian Weimer Avatar answered Nov 15 '22 00:11

Florian Weimer