Fix closure capturing bug with for loops

This commit is contained in:
Laurenz 2022-12-01 15:05:57 +01:00
parent e1e93938a1
commit 33ab1fdbdd
2 changed files with 7 additions and 2 deletions

View File

@ -1008,10 +1008,11 @@ impl Eval for ast::ForLoop {
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
let flow = vm.flow.take();
let mut output = Value::None;
vm.scopes.enter();
macro_rules! iter {
(for ($($binding:ident => $value:ident),*) in $iter:expr) => {{
vm.scopes.enter();
#[allow(unused_parens)]
for ($($value),*) in $iter {
$(vm.scopes.top.define($binding.clone(), $value);)*
@ -1031,10 +1032,12 @@ impl Eval for ast::ForLoop {
}
}
vm.scopes.exit();
}};
}
let iter = self.iter().eval(vm)?;
let pattern = self.pattern();
let key = pattern.key().map(ast::Ident::take);
let value = pattern.value().take();
@ -1076,7 +1079,6 @@ impl Eval for ast::ForLoop {
vm.flow = flow;
}
vm.scopes.exit();
Ok(output)
}
}

View File

@ -329,12 +329,14 @@ impl<'a> CapturesVisitor<'a> {
// evaluated.
Some(ast::Expr::For(expr)) => {
self.visit(expr.iter().as_untyped());
self.internal.enter();
let pattern = expr.pattern();
if let Some(key) = pattern.key() {
self.bind(key);
}
self.bind(pattern.value());
self.visit(expr.body().as_untyped());
self.internal.exit();
}
// An import contains items, but these are active only after the
@ -416,6 +418,7 @@ mod tests {
// For loop.
test("#for x in y { x + z }", &["y", "z"]);
test("#for x, y in y { x + y }", &["y"]);
test("#for x in y {} #x", &["x", "y"]);
// Import.
test("#import x, y from z", &["z"]);