I'm trying to iterate over a vector of statements and match (or double match) the results from evaluating them. I think the root cause of my error is the immutable borrow from iterating: for stmt in &self.statements
I'm totally fine changing my whole design if I've worked myself into a corner here.
I thought mutable borrows during an immutable borrow is fine,as long as there is only one user/consumer of the mutable borrow at a time.
The error:
Checking rust-playground v0.1.0 (C:\Users\joraki\projects\rust-playground)
error[E0502]: cannot borrow `*self` as mutable because it is also borrowed as immutable
--> src\main.rs:25:29
|
18 | for stmt in &self.statements {
| ----------------
| |
| immutable borrow occurs here
| immutable borrow later used here
...
25 | Err(err) => self.runtime_error(&err)
| ^^^^^^^^^^^^^^^^^^^^^^^^ mutable borrow occurs here
For more information about this error, try `rustc --explain E0502`.
error: could not compile `rust-playground` due to previous error
Here refers to for stmt in &self.statements
fn main() {
println!("Hello, world!");
}
#[derive(PartialEq, Debug)]
pub enum Stmt {
Expression(String),
Print(String)
}
pub struct Interpreter {
statements: Vec<Stmt>,
runtime_error: bool
}
impl Interpreter {
pub fn interpret(&mut self) {
for stmt in &self.statements {
let result = self.evaluate(stmt);
match result {
Ok(x) => match x {
Some(y) => println!("{}", y),
None => println!("No value returned. No errors.")
},
Err(err) => self.runtime_error(&err)
}
}
}
fn runtime_error(&mut self, err: &str) {
self.runtime_error = true;
println!("{}", err);
}
fn evaluate(&self, stmt: &Stmt) -> Result<Option<String>, String> {
match stmt {
Stmt::Expression(expr) => {
Ok(Some(expr.to_string()))
},
Stmt::Print(expr) => Err(format!("Something bad happened - {}", expr))
}
}
}