mirror of
https://github.com/typst/typst
synced 2025-05-13 20:46:23 +08:00
Fix closure capturing bug with for loops
This commit is contained in:
parent
e1e93938a1
commit
33ab1fdbdd
@ -1008,10 +1008,11 @@ impl Eval for ast::ForLoop {
|
|||||||
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
|
fn eval(&self, vm: &mut Vm) -> SourceResult<Self::Output> {
|
||||||
let flow = vm.flow.take();
|
let flow = vm.flow.take();
|
||||||
let mut output = Value::None;
|
let mut output = Value::None;
|
||||||
vm.scopes.enter();
|
|
||||||
|
|
||||||
macro_rules! iter {
|
macro_rules! iter {
|
||||||
(for ($($binding:ident => $value:ident),*) in $iter:expr) => {{
|
(for ($($binding:ident => $value:ident),*) in $iter:expr) => {{
|
||||||
|
vm.scopes.enter();
|
||||||
|
|
||||||
#[allow(unused_parens)]
|
#[allow(unused_parens)]
|
||||||
for ($($value),*) in $iter {
|
for ($($value),*) in $iter {
|
||||||
$(vm.scopes.top.define($binding.clone(), $value);)*
|
$(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 iter = self.iter().eval(vm)?;
|
||||||
|
|
||||||
let pattern = self.pattern();
|
let pattern = self.pattern();
|
||||||
let key = pattern.key().map(ast::Ident::take);
|
let key = pattern.key().map(ast::Ident::take);
|
||||||
let value = pattern.value().take();
|
let value = pattern.value().take();
|
||||||
@ -1076,7 +1079,6 @@ impl Eval for ast::ForLoop {
|
|||||||
vm.flow = flow;
|
vm.flow = flow;
|
||||||
}
|
}
|
||||||
|
|
||||||
vm.scopes.exit();
|
|
||||||
Ok(output)
|
Ok(output)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -329,12 +329,14 @@ impl<'a> CapturesVisitor<'a> {
|
|||||||
// evaluated.
|
// evaluated.
|
||||||
Some(ast::Expr::For(expr)) => {
|
Some(ast::Expr::For(expr)) => {
|
||||||
self.visit(expr.iter().as_untyped());
|
self.visit(expr.iter().as_untyped());
|
||||||
|
self.internal.enter();
|
||||||
let pattern = expr.pattern();
|
let pattern = expr.pattern();
|
||||||
if let Some(key) = pattern.key() {
|
if let Some(key) = pattern.key() {
|
||||||
self.bind(key);
|
self.bind(key);
|
||||||
}
|
}
|
||||||
self.bind(pattern.value());
|
self.bind(pattern.value());
|
||||||
self.visit(expr.body().as_untyped());
|
self.visit(expr.body().as_untyped());
|
||||||
|
self.internal.exit();
|
||||||
}
|
}
|
||||||
|
|
||||||
// An import contains items, but these are active only after the
|
// An import contains items, but these are active only after the
|
||||||
@ -416,6 +418,7 @@ mod tests {
|
|||||||
// For loop.
|
// For loop.
|
||||||
test("#for x in y { x + z }", &["y", "z"]);
|
test("#for x in y { x + z }", &["y", "z"]);
|
||||||
test("#for x, y in y { x + y }", &["y"]);
|
test("#for x, y in y { x + y }", &["y"]);
|
||||||
|
test("#for x in y {} #x", &["x", "y"]);
|
||||||
|
|
||||||
// Import.
|
// Import.
|
||||||
test("#import x, y from z", &["z"]);
|
test("#import x, y from z", &["z"]);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user