[Question] Borrowing problem when looping

While looping some datastructures returned from a function I find myself fighting the compiler over my own data structure like a reader fighting a librarian over borrowing "me own book". I know, I am not seeing something, so I turn to the community once more.

This is the relevant code:

   93 pub trait TRecord: Send {
   94     fn copy(&self) -> Box<dyn TRecord>;
   95     /// The name of the record
   96     fn name(&self) -> String;
   97     /// identifier returns an option of the field_name if it identifies the record
   98     fn identifier(&self) -> Option<String>;
   99     /// Fields contains the definition of each field in this record
  100     fn fields(&self) -> Vec<Field>;
  101     /// data contains the contents per field by field_name
  102     fn data(&self) -> HashMap<String, String>;
  103     /// update record using new data
  104     fn update(&mut self, fields: HashMap<String, String>) -> Result<(), String>;
  105 }
  107 impl std::fmt::Debug for TRecord {
  108     fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
  109         let mut msg = String::new();
  110         for field in &self.fields() {
  111             let field_name = field.name();
✖ 112             let data = self.data().get(&field_name).unwrap(); temporary value dropped while borrowed    creates 
ℹ 113             msg = msg + &field_name + ", " + data; temporary value dropped while borrowed    borrow later used h
  114         }
  115         write!(f, "{}", msg)
  116     }
  117 }

As the inline warning is incompletely visible, I include the compiler error:

error[E0716]: temporary value dropped while borrowed
   --> src/mvc.rs:112:24
112 |             let data = self.data().get(&field_name).unwrap();
    |                        ^^^^^^^^^^^                          - temporary value is freed at the end of this statement
    |                        |
    |                        creates a temporary which is freed while still in use
113 |             msg = msg + &field_name + ", " + data;
    |                                              ---- borrow later used here
    = note: consider using a `let` binding to create a longer lived value

error: aborting due to previous error

For more information about this error, try `rustc --explain E0716`.
error: Could not compile `mvc`.

To learn more, run the command again with --verbose.

What am I overlooking here? How am I supposed to loop over these structures? If I need to add some more info, let me know.

You have to keep the HashMap around while you borrow from it.

let data = self.data();
let data = data.get(&field_name).unwrap();

In one line the HashMap is not around anymore it's like:

//          ▼ doesn't exist
let data = data.get(&field_name).unwrap();

Thank you very much! That solved the problem. Also, good explanation, I get it now, thanks!

This topic was automatically closed 90 days after the last reply. New replies are no longer allowed.