Help understanding compiler error "cannot move out of borrowed content"


#1

I’m trying to learn rust for the nth time, and I’m having trouble understanding what the compiler is trying to tell me:

https://play.rust-lang.org/?gist=d9ad48f59313e3c61fcb96a467461f91

The second question I have: I’m assuming that the code I’m writing isn’t idiomatic rust, since I’m coming at it in a “C thinking” mode. Is there a way of writing it in a more idiomatic rust way?

Thanks!


#2

The problem is that you don’t own the data you’re trying to consume. The problem is with this line:

let mut iter = self.node_list.into_iter();

into_iter's definition is fn into_iter(self) -> Self::IntoIter;. It consumes self and turns it into a Self::IntoIter. You can’t do this, because you don’t own self, you borrow it:

fn map_label(&self, lbl: &mut Label) {
             ^^^^^

Does this make sense so far?


#3

Here is one option.

There are a few issues here:

  1. some_value.field = another_value.field will attempt to move field from another_value unless the field is a Copy type. So I made your LabelType derive Copy. You can also make it derive just Clone, and then do some_value.field = another_value.field.clone().
  2. into_iter() is a consuming method - you’ll note that it takes self. But you can’t consume something if you don’t own it, and that’s the gist of your “cannot move out of borrowed content” - the compiler is trying to move, say, node_list out of Thing but you only have a borrow of Thing.
  3. map_labels and map_label cannot work as methods. map_labels needs to take a mutable borrow to self so it can in turn take a mutable borrow of Label. If you’re holding a mutable borrow of a Label, you cannot call another method on Thing while that mutable borrow is in scope. The compiler has no way of knowing that map_label accesses a disjoint set of fields in Thing. So in my example above, map_label is made into an associated function, and we pass it the &[Node] slice explicitly.

I’ll stop here and let you ask any questions up to this point.


#4

I think the part I was missing is that into_iter consumes, it’s starting to make more sense now.

Thanks!