'Understanding Rust `Rc<RefCell<_>>`

I'm trying to create a tree with a type definition similar to

#[derive(Debug, Clone)]
pub(crate) struct TreeBox<T> {
    root: Option<Box<NodeBox<T>>>,
}

#[derive(Debug, Clone)]
struct NodeBox<T> {
    value: T,
    left: Option<Box<NodeBox<T>>>,
    right: Option<Box<NodeBox<T>>>,
}

With insert function

impl<T: Ord> TreeBox<T> {
    fn new() -> Self {
        Self { root: None }
    }

    pub fn insert(&mut self, value: T) -> bool {
        let mut node = &mut self.root;

        while let Option::Some(current_node) = node {
            match current_node.value.cmp(&value) {
                Ordering::Less => node = &mut current_node.right,
                Ordering::Equal => return false,
                Ordering::Greater => node = &mut current_node.left,
            }
        }

        *node = Option::Some(Box::new(NodeBox {
            value,
            left: Option::None,
            right: Option::None,
        }));

        return true;
    }
}

This works perfectly and I'm very happy with the implementation. However I want to store a reference from each node to it's parent. After some research I found this article describing an implementation using RefCell and Weak structs.

With this knowledge my plan was to update the example from above. My idea was that I could just substitute Box<...> with Rc<RefCell<..>>. My thinking was that these types are very similar in that they both store a reference to some data structure, only difference is that there can be multiple Rc<RefCell<..>>'s pointing to that data structure. I changed my implementation to

#[derive(Debug, Clone)]
pub(crate) struct Tree<T> {
    root: Option<Rc<RefCell<Node<T>>>>,
}

#[derive(Debug, Clone)]
struct Node<T> {
    value: T,
    left: Option<Rc<RefCell<Node<T>>>>,
    right: Option<Rc<RefCell<Node<T>>>>,
}

impl<T: Ord> Tree<T> {
    fn new() -> Self {
        Self { root: None }
    }

    pub fn insert(&mut self, value: T) -> bool {
        let mut node = &mut self.root;

        while let Option::Some(current_node) = node {
            let cmp = current_node.borrow().value.cmp(&value);
            match cmp {
                Ordering::Less => node = &mut current_node.borrow_mut().right,
                Ordering::Equal => return false,
                Ordering::Greater => node = &mut current_node.borrow_mut().left,
            };
        }

        *node = Option::Some(Rc::new(RefCell::new(Node {
            value,
            left: Option::None,
            right: Option::None,
        })));

        return true;
    }
}

However this updated example doesn't run, saying

error[E0716]: temporary value dropped while borrowed
  --> src/lib.rs:28:47
   |
28 |                 Ordering::Less => node = &mut current_node.borrow_mut().right,
   |                                               ^^^^^^^^^^^^^^^^^^^^^^^^^     -
   |                                               |                             |
   |                                               |                             temporary value is freed at the end of this statement
   |                                               |                             ... and the borrow might be used here, when that temporary is dropped and runs the destructor for type `RefMut<'_, Node<T>>`
   |                                               creates a temporary which is freed while still in use
   |                                               a temporary with access to the borrow is created here ...
   |
   = note: consider using a `let` binding to create a longer lived value

Is my example wrong, or is there something I still don't quite understand about rusts Rc<RefCell<_>>?

A link to a playground with the examples from above: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=9929b2118e2430f03035da4c65a4cf2f



Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source