Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

How to handle `<Option<Box<_>>>` in Rust?

The code:

pub struct Scope<'a> {
    pub parent: Option<Box<Scope<'a>>>,
    pub vars: HashMap<&'a str, Value>,
}

impl<'a> Scope<'a> {
    pub fn get(&self, name: &str) -> Result<&Value, String> {
        if let Some(v) = self.vars.get(name) {
            Ok(v)
        } else if let Some(parent) = self.parent { // <- error here
            parent.get(name) // <- and here
        } else {
            Err(format!("{} is undefined", name))
        }
    }
}

And the compiler gives me this error:

error[E0507]: cannot move out of `self.parent` as enum variant `Some` which is behind a shared reference
  --> src/interpreter/scope.rs:13:38
   |
13 |         } else if let Some(parent) = self.parent {
   |                            ------    ^^^^^^^^^^^ help: consider borrowing here: `&self.parent`
   |                            |
   |                            data moved here
   |                            move occurs because `parent` has type `Box<scope::Scope<'_>>`, which does not implement the `Copy` trait

error[E0515]: cannot return reference to local data `*parent`
  --> src/interpreter/scope.rs:14:13
   |
14 |             parent.get(name)
   |             ^^^^^^^^^^^^^^^^ returns a reference to data owned by the current function

I have no idea how to fix this error. How can I fix this?

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

Thanks in advance.

>Solution :

You are transfering the ownership of the value inside self.parent. By doing let Some(parent) = self.parent now the value that was on self.parent is owned by parent. This would cause self.parent to be undefined because there can only be one owner at a time, hence the compilation error.

See ownership rules on the rust book

You can instead borrow self.parent as suggested:

impl<'a> Scope<'a> {
    pub fn get(&self, name: &str) -> Result<&Value, String> {
        if let Some(v) = self.vars.get(name) {
            Ok(v)
        } else if let Some(parent) = &self.parent { // <- borrowing self.parent
            parent.get(name) // <- and here
        } else {
            Err(format!("{} is undefined", name))
        }
    }
}
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading