2

I am creating a binary tree with a node defined like this:

use std::cell::{Ref, RefCell};

pub struct Node<T>
where
    T: Copy + PartialOrd + std::fmt::Display,
{
    data: T,
    left: Option<RefCell<Box<Node<T>>>>,
    right: Option<RefCell<Box<Node<T>>>>,
}

I am trying to implement a function find which should take a root node and a key and return a reference to the node which matches the given key. I tried to implement find recursively but I am having trouble taking the left and right subtree out of the Option and RefCell.

fn find<T>(node: Ref<Box<Node<T>>>, data: T) -> Option<Ref<Box<Node<T>>>>
where
    T: Copy + PartialOrd + std::fmt::Display,
{
    if node.data == data {
        return Some(node);
    } else if node.data > data {
        if node.left.is_some() {
            // Error: Cannot move out of borrowed content
            let myref = node.left.unwrap().borrow();
            return find(myref, data);
        } else {
            return None;
        }
    } else {
        if node.right.is_some() {
            // Error: returns a value referencing data owned by the current function
            let myref = node.right.as_ref().unwrap().borrow();
            return find(myref, data);
        } else {
            return None;
        }
    }
}
error[E0507]: cannot move out of borrowed content
  --> src/lib.rs:21:25
   |
21 |             let myref = node.left.unwrap().borrow();
   |                         ^^^^^^^^^ cannot move out of borrowed content

error[E0515]: cannot return value referencing temporary value
  --> src/lib.rs:22:20
   |
21 |             let myref = node.left.unwrap().borrow();
   |                         ------------------ temporary value created here
22 |             return find(myref, data);
   |                    ^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function

error[E0515]: cannot return value referencing function parameter `node`
  --> src/lib.rs:30:20
   |
29 |             let myref = node.right.as_ref().unwrap().borrow();
   |                         ---- `node` is borrowed here
30 |             return find(myref, data);
   |                    ^^^^^^^^^^^^^^^^^ returns a value referencing data owned by the current function
Shepmaster
  • 388,571
  • 95
  • 1,107
  • 1,366
Ankit
  • 423
  • 2
  • 12
  • 1
    I believe your question is answered by the answers of [Cyclic reference of RefCell borrows in traversal](https://stackoverflow.com/q/36597987/155423). If you disagree, please **[edit]** your question to explain the differences. Otherwise, we can mark this question as already answered. – Shepmaster May 09 '19 at 14:48
  • See also [How do I return a reference to something inside a RefCell without breaking encapsulation?](https://stackoverflow.com/q/29401626/155423) and [How do I borrow a RefCell, find a key, and return a reference to the result? [duplicate]](https://stackoverflow.com/q/30281664/155423) – Shepmaster May 09 '19 at 14:57
  • @Shepmaster Using Rc as done in the linked answer, solves the problem. Thanks. – Ankit May 09 '19 at 16:49

0 Answers0