<Rc<RefCell<TreeNode>>> on Leetcode

I need help understanding this error. How do I get a mutable reference to the TreeNode in root? Root is defined as:

// Definition for a binary tree node.
// #[derive(Debug, PartialEq, Eq)]
// pub struct TreeNode {
//   pub val: i32,
//   pub left: Option<Rc<RefCell<TreeNode>>>,
//   pub right: Option<Rc<RefCell<TreeNode>>>,
// }
// impl TreeNode {
//   #[inline]
//   pub fn new(val: i32) -> Self {
//     TreeNode {
//       val,
//       left: None,
//       right: None
//     }
//   }
// }


Line 41, Char 26: borrow of moved value: `rootTreeNode` (solution.rs)
26 |         let mut rootTreeNode = Rc::try_unwrap(root.unwrap()).unwrap().into_inner(); // I've borrowed the RefCell instance
   |             ---------------- move occurs because `rootTreeNode` has type `tree_node::TreeNode`, which does not implement the `Copy` trait

You don't want into_inner() nor try_unwrap(). As evident from their name and documentation, they consume the wrapper (the RefCell and the Rc, respectively), returning the wrapped value by-value.

If you need a mutable reference to the inner value, use RefCell::borrow_mut() instead. That's the whole point of using a RefCell.


Recommended reading: Introduction - Learning Rust With Entirely Too Many Linked Lists


That's the fact that into is used to denote something owning and moving. E.g. into_inner and into_string

borrow or as are used to show taking a reference. E.g. borrow_mut and as_str

If something gives a mutable reference, it's going to have _mut added to the end.

Related is the trio of iterators:
iter - borrows
into_iter - moves into an iterator of owned values
iter_mut - mutable borrows

The stdlib leads the way with these conventions, you won't go far wrong doing similar in your own crates.

At least, that's my understanding

1 Like

Can someone explain why Rc and RefCell are used here? I'm not entirely sure I understand the benefit.

Perhaps to avoid unsafe code? But I don't think it is sound to expose Rc as a pub member in TreeNode.

OK, so let's take a step back. What are the purpose of Rc and RefCell?

Check out this:


Thank you, this helped a lot.

Please do not use LeetCode as a resource for learning Rust because it's terrible. I go into details why in this article but the TL;DR is if you want to practice Rust doing small exercise then: do Rustlings first, then do Exercism's Rust Track.


Thank you!