feat(es/minifier): Remove unused args for IIFE#11536
feat(es/minifier): Remove unused args for IIFE#11536Austaras wants to merge 1 commit intoswc-project:mainfrom
Conversation
|
There was a problem hiding this comment.
Pull request overview
This PR enhances the SWC ECMAScript minifier’s IIFE argument optimization to remove unused call arguments (addressing the first part of #11089), and updates large golden outputs accordingly.
Changes:
- Update
ignore_unused_args_of_iifeto drop/neutralize unused IIFE call arguments, including removing trailing arguments when safe. - Add an
eval-presence guard (contains_eval) to avoid unsafe transformations. - Refresh expected outputs for large fixtures/bench outputs to reflect the new minification result.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 3 comments.
| File | Description |
|---|---|
crates/swc_ecma_minifier/src/compress/optimize/iife.rs |
Implements removal of unused/trailing IIFE call arguments and adds eval guard. |
crates/swc_ecma_minifier/tests/fixture/next/react-pdf-renderer/output.js |
Updates expected minified output to reflect dropped unused IIFE args. |
crates/swc_ecma_minifier/tests/benches-full/victory.js |
Updates expected benchmark output with removed unused IIFE call argument. |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| if e.args.len() > params.len() { | ||
| for i in (params.len()..e.args.len()).rev() { | ||
| if let Some(arg) = e.args.get_mut(i) { | ||
| let new = self.ignore_return_value(&mut arg.expr); | ||
|
|
||
| if let Some(new) = new { | ||
| arg.expr = Box::new(new); | ||
| } else { | ||
| e.args.remove(i); | ||
| } | ||
| } | ||
| } | ||
| } |
There was a problem hiding this comment.
This change introduces new behavior (dropping trailing IIFE call arguments) with several tricky edge cases (e.g. spread args, rest params, side-effect-only rewrites). Please add a focused regression fixture/test that covers the reported pattern from #11089 and at least one spread/rest scenario, so future optimizer changes don't reintroduce incorrect argument dropping.
| if e.args.len() > params.len() { | ||
| for i in (params.len()..e.args.len()).rev() { | ||
| if let Some(arg) = e.args.get_mut(i) { | ||
| let new = self.ignore_return_value(&mut arg.expr); | ||
|
|
There was a problem hiding this comment.
The new trailing-argument removal loop ignores arg.spread. For a call like (function(){})(...xs) or (function(a){})(x, ...xs), removing a spread argument is not semantics-preserving because spreading triggers iterator evaluation (can throw / have side effects) even if arg.expr itself looks side-effect-free. Add a guard to bail out when any argument has spread, or at least skip/abort removal when arg.spread.is_some() inside this loop.
Binary Sizes
Commit: ad96e3c |
CodSpeed Performance ReportMerging this PR will not alter performanceComparing Summary
|
Description:
BREAKING CHANGE:
Related issue (if exists):
First part of #11089