Skip to content

fix(es/minifier): preserve args for destructured callbacks#11830

Merged
kdy1 merged 4 commits intoswc-project:mainfrom
kdy1:kdy1/fix-11829-minified-call-args
May 4, 2026
Merged

fix(es/minifier): preserve args for destructured callbacks#11830
kdy1 merged 4 commits intoswc-project:mainfrom
kdy1:kdy1/fix-11829-minified-call-args

Conversation

@kdy1
Copy link
Copy Markdown
Member

@kdy1 kdy1 commented Apr 28, 2026

Description:

Fixes a minifier regression where unused/call argument optimization could drop arguments for a callback loaded from destructuring and then conditionally assigned a zero-arity fallback. Destructured bindings with initializers now keep callback arity unknown, while direct function/arrow initializers still retain precise arity inference.

Added a regression fixture for the reported cb("value") case.

BREAKING CHANGE:

None.

Related issue (if exists):

Fixes #11829

Copilot AI review requested due to automatic review settings April 28, 2026 04:07
@kdy1 kdy1 requested a review from a team as a code owner April 28, 2026 04:07
kodiakhq[bot]
kodiakhq Bot previously approved these changes Apr 28, 2026
@changeset-bot
Copy link
Copy Markdown

changeset-bot Bot commented Apr 28, 2026

⚠️ No Changeset found

Latest commit: 948cb08

Merging this PR will not cause a version bump for any packages. If these changes should not result in a new version, you're good to go. If these changes should result in a version bump, you need to add a changeset.

Click here to learn what changesets are, and how to add one.

Click here if you're a maintainer who wants to add a changeset to this PR

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Fixes a SWC minifier regression where call-argument dropping could incorrectly remove arguments when a callback is obtained via destructuring and later conditionally replaced with a zero-arity fallback.

Changes:

  • Update usage analysis to treat variables introduced via destructuring patterns as having unknown callable arity (param_count = Unknown).
  • Preserve precise arity inference for direct identifier initializers that are function/arrow expressions.
  • Add a regression fixture for issue #11829 validating the runtime behavior (cb("value") still receives its argument).

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 1 comment.

Show a summary per file
File Description
crates/swc_ecma_minifier/src/usage_analyzer/analyzer/mod.rs Ensures destructured bindings are marked with unknown arity to prevent unsafe argument dropping.
crates/swc_ecma_minifier/tests/terser/compress/drop_unused/issue_11829/input.js Repro case demonstrating destructured callback with conditional fallback.
crates/swc_ecma_minifier/tests/terser/compress/drop_unused/issue_11829/config.json Compressor configuration reproducing the problematic optimization scenario.
crates/swc_ecma_minifier/tests/terser/compress/drop_unused/issue_11829/expected.stdout Runtime assertion to catch missing-argument behavior (expects PASS).
crates/swc_ecma_minifier/tests/terser/compress/drop_unused/issue_11829/output.js Empty output golden to make this fixture validate runtime output rather than exact printed code.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1523 to +1524
// Destructuring pulls values from an external object or iterable, so the
// callable arity of each binding is not known from this declaration.
Copy link

Copilot AI Apr 28, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The comment claims destructuring always pulls values from an external object/iterable, but destructuring can also read from literals (e.g. let { cb } = { cb(){} }). Consider rewording to reflect the real invariant: for destructured bindings, callable arity can't be inferred reliably from the declarator, so the binding’s param_count is forced to Unknown for correctness.

Suggested change
// Destructuring pulls values from an external object or iterable, so the
// callable arity of each binding is not known from this declaration.
// For destructured bindings, the callable arity of each bound value cannot
// be inferred reliably from the declarator, so conservatively mark it unknown.

Copilot uses AI. Check for mistakes.
@github-actions
Copy link
Copy Markdown
Contributor

github-actions Bot commented Apr 28, 2026

Binary Sizes

File Size
swc.linux-x64-gnu.node 27M (27759432 bytes)

Commit: 76bf6e8

@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Apr 28, 2026

Merging this PR will improve performance by 2.06%

⚡ 1 improved benchmark
✅ 218 untouched benchmarks
⏩ 31 skipped benchmarks1

Performance Changes

Benchmark BASE HEAD Efficiency
es/large/minify/libraries/terser 519.4 ms 508.9 ms +2.06%

Comparing kdy1:kdy1/fix-11829-minified-call-args (948cb08) with main (16a56d0)2

Open in CodSpeed

Footnotes

  1. 31 benchmarks were skipped, so the baseline results were used instead. If they were deleted from the codebase, click here and archive them to remove them from the performance reports.

  2. No successful run was found on main (426183b) during the generation of this report, so 16a56d0 was used instead as the comparison base. There might be some changes unrelated to this pull request in this report.

@kdy1 kdy1 enabled auto-merge (squash) April 28, 2026 05:10
kodiakhq[bot]
kodiakhq Bot previously approved these changes Apr 28, 2026
@kdy1 kdy1 disabled auto-merge April 28, 2026 07:42
Copilot AI review requested due to automatic review settings May 2, 2026 13:15
@Austaras
Copy link
Copy Markdown
Member

Austaras commented May 2, 2026

Maybe we should tech AI to respect MSRV. Also never add tests to terser tests.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +1522 to +1528
} else {
// Destructuring pulls values from an external object or iterable, so the
// callable arity of each binding is not known from this declaration.
for id in find_pat_ids(&decl.name) {
self.data
.var_or_default(id)
.store_param_count(Value::Unknown);
Comment on lines +1522 to +1528
} else {
// Destructuring pulls values from an external object or iterable, so the
// callable arity of each binding is not known from this declaration.
for id in find_pat_ids(&decl.name) {
self.data
.var_or_default(id)
.store_param_count(Value::Unknown);
kdy1 added a commit that referenced this pull request May 4, 2026
**Description:**

Adds agent guidance requested from PR review feedback:

- Respect the project MSRV when writing Rust code.
- Keep new swc_ecma_minifier regression coverage out of tests/terser and
prefer SWC-owned fixtures such as tests/fixture/issues.

This is documentation-only and helps future automated edits choose the
right compatibility and fixture behavior.

**Related issue:**

Refs
#11830 (comment)
@kdy1 kdy1 merged commit 21873b0 into swc-project:main May 4, 2026
76 checks passed
@kdy1 kdy1 deleted the kdy1/fix-11829-minified-call-args branch May 4, 2026 02:00
@kdy1
Copy link
Copy Markdown
Member Author

kdy1 commented May 4, 2026

Thank you!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

Minified function call omits argument(s)

3 participants