title: Unwrap and access T from an Option<Rc<RefCell<T>>>
body: <p>I am trying to solve some Leetcode problems with Rust. However, I ran into some difficulties with LeetCode's <code>TreeNode</code> implementation. </p>
  
  <pre><code>use std::cell::RefCell;
  use std::rc::Rc;
  
  // TreeNode data structure
  #[derive(Debug, PartialEq, Eq)]
  pub struct TreeNode {
      pub val: i32,
      pub left: Option&lt;Rc&lt;RefCell&lt;TreeNode&gt;&gt;&gt;,
      pub right: Option&lt;Rc&lt;RefCell&lt;TreeNode&gt;&gt;&gt;,
  }
  
  impl TreeNode {
      #[inline]
      pub fn new(val: i32) -&gt; Self {
          TreeNode {
              val,
              left: None,
              right: None,
          }
      }
  }
  </code></pre>
  
  <p>If I want to do an inorder traversal, how to unwrap the <code>TreeNode</code>'s <code>Option&lt;Rc&lt;RefCell&lt;TreeNode&gt;&gt;&gt;</code> object, access its <code>.val</code> <code>.left</code> <code>.right</code> and pass them as inputs into a recursive function?</p>
  
  <p>I have tried:</p>
  
  <pre><code>pub struct Solution;
  
  impl Solution {
      pub fn inorder_traversal(root: Option&lt;Rc&lt;RefCell&lt;TreeNode&gt;&gt;&gt;) -&gt; Vec&lt;i32&gt; {
          let mut ret: Vec&lt;i32&gt; = vec![];
          match root {
              Some(V) =&gt; Solution::helper(&amp;Some(V), &amp;mut ret),
              None =&gt; (),
          }
  
          ret
      }
  
      fn helper(node: &amp;Option&lt;Rc&lt;RefCell&lt;TreeNode&gt;&gt;&gt;, ret: &amp;mut Vec&lt;i32&gt;) {
          match node {
              None =&gt; return,
              Some(V) =&gt; {
                  // go to the left branch
                  Solution::helper(
                      (*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
                          .into_inner()
                          .left,
                      ret,
                  );
                  // push root value on the vector
                  ret.push(Rc::try_unwrap(Rc::clone(V)).unwrap_err().into_inner().val);
                  // go right branch
                  Solution::helper(
                      (*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
                          .into_inner()
                          .right,
                      ret,
                  );
              }
          }
      }
  }
  
  fn main() {}
  </code></pre>
  
  <p>(<a href="https://play.rust-lang.org/?version=stable&amp;mode=debug&amp;edition=2018&amp;gist=99b7fd163ad8179d1d63e7383b1a99dc" rel="noreferrer">Playground</a>)</p>
  
  <p>The compiler complains:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0308]: mismatched types
    --&gt; src/lib.rs:42:21
     |
  42 | /                     (*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
  43 | |                         .into_inner()
  44 | |                         .left,
     | |_____________________________^ expected reference, found enum `std::option::Option`
     |
     = note: expected type `&amp;std::option::Option&lt;std::rc::Rc&lt;std::cell::RefCell&lt;TreeNode&gt;&gt;&gt;`
                found type `std::option::Option&lt;std::rc::Rc&lt;std::cell::RefCell&lt;TreeNode&gt;&gt;&gt;`
  help: consider borrowing here
     |
  42 |                     &amp;(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
  43 |                         .into_inner()
  44 |                         .left,
     |
  </code></pre>
  
  <p>But if I try the suggestion, it complains as well:</p>
  
  <pre class="lang-none prettyprint-override"><code>error[E0507]: cannot move out of an `Rc`
    --&gt; src/lib.rs:42:22
     |
  42 |                     &amp;(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
     |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ cannot move out of an `Rc`
  
  error[E0507]: cannot move out of data in a `&amp;` reference
    --&gt; src/lib.rs:42:22
     |
  42 |                     &amp;(*Rc::try_unwrap(Rc::clone(V)).unwrap_err())
     |                      ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
     |                      |
     |                      cannot move out of data in a `&amp;` reference
     |                      cannot move
  </code></pre>