mirror of
https://github.com/oxc-project/oxc.git
synced 2026-11-04 10:29:58 +00:00
fix(minifier): preserve default parameter side effects (#24791)
Pure-function summaries currently treat functions with identifier parameters as side-effect-free without checking parameter initializers. This lets dead-code elimination remove calls that must evaluate a default value.
For example:
```js
var foo = (a = side_effect()) => {};
foo();
```
Before this change, the call is removed entirely. After this change, it is preserved so `side_effect()` runs.
This skips the summary when an ordinary parameter has a default initializer and adds regression coverage for both arrow functions and function declarations.
Verified with `cargo test -p oxc_minifier`, `just minsize`, `cargo clippy -p oxc_minifier -- -D warnings`, and `just fmt`. No minsize or allocation snapshot changed.
Implemented with AI assistance (OpenAI Codex and Claude). Claude identified the bug during review; Codex implemented and verified the fix. The contributor remains responsible for reviewing and understanding the change.
This commit is contained in:
1 parent
334d8848ff
commit
23b904ff09
2 files changed
+16
-2
No files matched your search
@@ -485,8 +485,14 @@ impl<'a> PeepholeOptimizations {
|
||||
if r#async || generator {
|
||||
return;
|
||||
}
|
||||
// `function foo({}) {} foo(null)` is runtime type error.
|
||||
if !params.items.iter().all(|pat| pat.pattern.is_binding_identifier()) {
|
||||
// Destructuring can throw. Default initializers run for missing or `undefined`
|
||||
// arguments, and function summaries are call-independent, so reject an initializer
|
||||
// that may have side effects. TDZ-only throws follow the minifier's documented
|
||||
// `No TDZ Violation` assumption.
|
||||
if !params.items.iter().all(|param| {
|
||||
param.pattern.is_binding_identifier()
|
||||
&& param.initializer.as_ref().is_none_or(|init| !init.may_have_side_effects(ctx))
|
||||
}) {
|
||||
return;
|
||||
}
|
||||
if body.statements.iter().any(|stmt| stmt.may_have_side_effects(ctx)) {
|
||||
|
||||
@@ -278,6 +278,14 @@ fn remove_empty_function() {
|
||||
test_options("var foo = () => {}; x = foo(a(), b())", "x = (a(), b(), void 0)", &options);
|
||||
test_options("var foo = function () {}; foo()", "", &options);
|
||||
|
||||
test_options("var foo = (a = 0) => {}; foo()", "", &options);
|
||||
test_options(
|
||||
"var foo = (a = side_effect()) => {}; foo()",
|
||||
"((a = side_effect()) => {})()",
|
||||
&options,
|
||||
);
|
||||
test_same_options("function foo(a = side_effect()) {} foo()", &options);
|
||||
|
||||
test_same_options("function foo({}) {} foo()", &options);
|
||||
test_options("var foo = ({}) => {}; foo()", "(({}) => {})()", &options);
|
||||
test_options("var foo = function ({}) {}; foo()", "(function ({}) {})()", &options);
|
||||
|
||||
Reference in new issue
Block a user