I've been making a quick an terrible code interpreter. However, when i was adding scopes to the execution all hell broke lose in this function. I've tried everything and in all other parts of the codebase it works. Now I can obviously refactor the code, but it feels like this should work. Can anyone explain this behaviour or what I'm obviously missing.
pub fn execute_body<'a,'b, T:Iterator<Item = &'a Statement>>(body:T,context:&'b mut ExecutionContext,scope:&'b mut Scope<'b>)->Rc<RefCell<Variable>>{
let mut last_rtn = None;
let mut skip_next = false;
let mut last_if_check = false;
for stm in body {
if !skip_next {
let a = execute_statement(stm, context,scope,Meta::default());
last_rtn = Some(a.clone());
}
skip_next = false;
if let Some(ref a) = last_rtn {
let r = a.borrow();
match *r {
Variable::DisallowExecuteNextStatement=>{skip_next = true;last_if_check=false},
Variable::AllowExecuteNextStatement=>{skip_next = false;last_if_check=true},
_=>{}
}
}
match stm{
Statement::ElseDirective=>{skip_next = last_if_check}
_=>{}
}
}
last_rtn.unwrap_or(context.undefined.clone())
}
I've toyed around with the life time parameters but it always results in roughly the same error. And again oddly enough every worked without the scope parameter
cannot borrow `*context` as mutable more than once at a time
`*context` was mutably borrowed here in the previous iteration of the loop
&'a mut Type<'a> is almost always wrong. Please search this forum for similar issues for an explanation. You'll likely need another lifetime parameter (if you want to be explicit; or just leaving off one of them should work, depending on which one you actually need).
It's not good practice to completely leave off the lifetime parameter of a generic type, though (because it's then syntactically unclear whether it has a lifetime). Specifically, the second variation would be better written as
Nevertheless, they do render your scope object useless, so you won't be able to get far with that signature. You will need to change it and likely refactor its callers.
I suspect you overconstrained a lifetime somewhere then that cascaded on you, propagating across types and functions. We may need to see the whole thing to detangle the lifetimes.
I've refactored now so that scopes now longer mut ref other scopes and that all scopes are owned by one object which also keeps track of the scope hierarchy