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?
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))
}
}
}