0

I have a tree structure that uses a HashMap in an RwLock to represent the children of a node, but my method to recurse down the tree to insert a value appears to an issue with lifetimes. A more full sample may be found here, but the relevant code is this:

struct Node<'a> {
    data: i32,
    children: RwLock<HashMap<String, Node<'a>>>,
    parent: Option<&'a Node<'a>> //necessary, as I need to be able to recurse back up the tree
}

impl<'a> Node<'a> {
    fn add_sequence(&'a self, key_list: Vec<String>, data: i32) {
        let mut key_iter = key_list.iter();
        let mut curr = self;

        let last = loop {
            let next = key_iter.next();
            if let None = next {return;}

            let key = next.unwrap();
            if curr.children.read().unwrap().contains_key(key) {
                curr = curr.children.read().as_ref().unwrap().get(key).unwrap();
            } else {
                break next.unwrap();
            }
        };
        curr.add_child(last.to_string(), data);
    }
}

This gives me the following error:

  --> src/main.rs:22:24
   |
11 | impl<'a> Node<'a> {
   |      -- lifetime `'a` defined here
...
22 |                 curr = curr.children.read().as_ref().unwrap().get(key).unwrap();
   |                        ^^^^^^^^^^^^^^^^^^^^---------                           - temporary value is freed at the end of this statement
   |                        |
   |                        creates a temporary which is freed while still in use
   |                        argument requires that borrow lasts for `'a`

I have tried solutions such as the one described in this answer, but I haven't been able to get it to work, possibly due to the process being iterative rather than one-time. How can I fix this error?

DanTheMan
  • 121
  • 1
  • 5
  • As far as I have learned it is impossible to store a owned value along a reference to this value. Yet this is the case when you add something into the childlist that references the parent (self). Using an `Rc` for parent and an `Rc` for children could be a solution. – CoronA May 28 '20 at 03:53
  • 1
    A first step could be this [example](https://play.rust-lang.org/?version=stable&mode=debug&edition=2018&gist=719fe5136d4c5b0efce5b154455cec5a) (it uses `Arc`, not `Rc` because `RwLock` does only make sense with concurrently accessed structures). It also feels a quite ugly solution (especially implementing the methods on `Arc` instead of `Node`). I am quite interested if someone finds a cleaner solution. – CoronA May 28 '20 at 04:33
  • 1
    Some alternatives can be found here: https://stackoverflow.com/questions/36167160/how-do-i-express-mutually-recursive-data-structures-in-safe-rust – CoronA May 28 '20 at 05:05
  • @CoronA Thank you, those links are a big help! I had considered using `Arc` like that, but it did feel inelegant to me as well. – DanTheMan May 28 '20 at 06:36

0 Answers0