Possible to give away the ownership of its field from a borrowed reference?

For example,

struct Foo {i: isize}
struct Bar {f: Foo}

fn main() {
  let foo = Foo{i: 0};
  let mut bar = Bar{f: foo};
  
  // #1: it seems fine to move its field if we have bar
  // let x = bar.f;
  
  let ref_bar = &mut bar;
  // #2: but it doesn't allow to move its field from a borrowed reference
  // let y = ref_bar.f;
}

At #1, the code is allowed to move a field if we have the struct. But if we only have a borrowed reference to the struct (#2), we can't move its field.

However, it seems pretty costly to keep a struct value all the time and pass it to functions (rustc needs to generate extra code to properly destroy it). And the field is not a Copy type, which means I cannot use Cell. What is the proper way to deal with this?

Thank you.

Since you've only borrowed it, Rust has to make sure that you leave the struct in good shape for the owner.

One possibility is to use Option<Foo> for that field. Then the &mut borrower can call .take() which leaves None in its place. This way the borrowed struct is still in a consistent state, but you've effectively taken ownership of the value you wanted.

3 Likes

That is exactly what I want. Thank you!