diff --git a/CHANGELOG.md b/CHANGELOG.md index 8598a79c..7627368d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ Buf fixes ---------- * `is_shared` is a reserved keyword and is now handled properly (e.g. it cannot be the target of a function pointer). +* Re-optimizing an AST via `optimize_ast` with constants now works correctly for closures. Previously the hidden `Share` nodes are not removed and causes variable-not-found errors during runtime if the constants are not available in the scope. New features ------------ diff --git a/src/optimizer.rs b/src/optimizer.rs index ea8f00d2..f4447556 100644 --- a/src/optimizer.rs +++ b/src/optimizer.rs @@ -840,6 +840,20 @@ fn optimize_stmt(stmt: &mut Stmt, state: &mut OptimizerState, preserve_result: b // return expr; Stmt::Return(Some(ref mut expr), ..) => optimize_expr(expr, state, false), + // Share nothing + Stmt::Share(x) if x.is_empty() => { + state.set_dirty(); + *stmt = Stmt::Noop(Position::NONE); + } + // Share constants + Stmt::Share(x) => { + let len = x.len(); + x.retain(|(v, _, _)| !state.find_constant(v).is_some()); + if x.len() != len { + state.set_dirty(); + } + } + // All other statements - skip _ => (), }