Skip to content

Conversation

@Austaras
Copy link
Member

@Austaras Austaras commented Dec 28, 2025

… IIFE

Description:

BREAKING CHANGE:

Related issue (if exists):
Closes #11368

Copilot AI review requested due to automatic review settings December 28, 2025 12:12
@Austaras Austaras requested a review from a team as a code owner December 28, 2025 12:12
@changeset-bot
Copy link

changeset-bot bot commented Dec 28, 2025

🦋 Changeset detected

Latest commit: a99de98

The changes in this PR will be included in the next version bump.

Not sure what this means? Click here to learn what changesets are.

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

Copy link
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

This PR fixes a bug in the ECMAScript minifier where IIFE (Immediately Invoked Function Expression) inlining was incorrectly applied in contexts where new identifiers cannot be added, particularly in class field initializers. The fix addresses issue #10931.

Key Changes:

  • Refactored IIFE inlining to use ExactSizeIterator instead of passing parameter length separately
  • Added stricter checks in can_extract_param to verify that arguments are simple literals when identifiers cannot be added
  • Removed the DontInvokeIife flag mechanism in favor of the more comprehensive may_add_ident() check

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 4 comments.

Show a summary per file
File Description
crates/swc_ecma_minifier/src/compress/optimize/iife.rs Refactored IIFE inlining functions to accept ExactSizeIterator parameters and added new validation logic to check argument types when identifiers cannot be added
crates/swc_ecma_minifier/src/compress/optimize/mod.rs Commented out the unused DontInvokeIife flag and its usage in class visitor
crates/swc_ecma_minifier/tests/fixture/issues/11368/input.js Added test case demonstrating the bug with class field initialization
crates/swc_ecma_minifier/tests/fixture/issues/11368/output.js Expected output showing the fix prevents incorrect inlining
Multiple test output files Updated expected outputs to reflect the fix preventing over-aggressive IIFE inlining

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

|| !matches!(
&*arg.expr,
Expr::Lit(
Lit::Num(..) | Lit::Str(..) | Lit::Bool(..) | Lit::BigInt(..)
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

The literal type check should include Lit::Null(..) to be consistent with other parts of the codebase. In other optimization functions like inline.rs and sequences.rs, null literals are treated as safe, side-effect-free values that can be inlined without creating variables. Omitting null from this check may unnecessarily prevent valid IIFE inlining optimizations when null is passed as an argument.

Suggested change
Lit::Num(..) | Lit::Str(..) | Lit::Bool(..) | Lit::BigInt(..)
Lit::Num(..)
| Lit::Str(..)
| Lit::Bool(..)
| Lit::BigInt(..)
| Lit::Null(..)

Copilot uses AI. Check for mistakes.
.ctx
.clone()
.with(BitCtx::DontInvokeIife, true)
// .with(BitCtx::DontInvokeIife, true)
Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

The commented-out code should be removed rather than left in place. This code is no longer needed after the refactoring, as evidenced by the removal of the DontInvokeIife flag usage throughout the codebase. Leaving commented code reduces readability and can cause confusion for future maintainers.

Suggested change
// .with(BitCtx::DontInvokeIife, true)

Copilot uses AI. Check for mistakes.
Comment on lines 456 to 460
// if self.ctx.bit_ctx.contains(BitCtx::DontInvokeIife) {
// log_abort!("iife: Inline is prevented");
// return false;
// }

Copy link

Copilot AI Dec 28, 2025

Choose a reason for hiding this comment

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

The commented-out code should be removed rather than left in place. This check is no longer needed after the refactoring, which now relies on the more comprehensive may_add_ident() check. Leaving commented code reduces readability and can cause confusion for future maintainers.

Suggested change
// if self.ctx.bit_ctx.contains(BitCtx::DontInvokeIife) {
// log_abort!("iife: Inline is prevented");
// return false;
// }

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

github-actions bot commented Dec 28, 2025

Binary Sizes

File Size
swc.linux-x64-gnu.node 28M (28527432 bytes)

Commit: c85e8ad

@codspeed-hq
Copy link

codspeed-hq bot commented Dec 28, 2025

CodSpeed Performance Report

Merging #11399 will not alter performance

Comparing Austaras:main (a99de98) with main (55a5083)

Summary

✅ 138 untouched

@kdy1 kdy1 changed the title fix(es/minifier): More strict check if cannot add ident when invoking… fix(es/minifier): More strict check if cannot add ident when invoking IIFE Dec 29, 2025
@kdy1 kdy1 added this to the Planned milestone Dec 29, 2025
Copy link
Member

@kdy1 kdy1 left a comment

Choose a reason for hiding this comment

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

Thank you!

Copilot AI review requested due to automatic review settings December 29, 2025 06:49
Copy link
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 8 out of 8 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 753 to 770
fn can_inline_fn_arg(usage: &VarUsageInfo, arg: &Expr) -> bool {
if usage.ref_count > 1
|| usage.assign_count > 0
|| usage.flags.contains(VarUsageInfoFlags::REASSIGNED)
|| usage.flags.contains(VarUsageInfoFlags::INLINE_PREVENTED)
{
return false;
}

match arg {
Expr::Lit(Lit::Num(..) | Lit::Str(..) | Lit::Bool(..) | Lit::BigInt(..)) => true,
Expr::Fn(..) if usage.can_inline_fn_once() => true,
_ => false,
}
}
Copy link

Copilot AI Dec 29, 2025

Choose a reason for hiding this comment

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

The condition usage.property_mutation_count == 0 check was removed from the inlining logic in inline_fn_param_stmt. Previously, the code checked this condition before inlining, but now can_inline_fn_arg doesn't verify property mutations. This could potentially lead to incorrect inlining when the parameter has property mutations. Consider adding this check to the can_inline_fn_arg function to maintain the same safety guarantees.

Copilot uses AI. Check for mistakes.
kdy1
kdy1 previously approved these changes Dec 29, 2025
@kdy1
Copy link
Member

kdy1 commented Dec 29, 2025

Thanks!

Copilot AI review requested due to automatic review settings December 29, 2025 07:58
@kdy1 kdy1 requested a review from a team as a code owner December 29, 2025 07:58
Copy link
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.

Copilot encountered an error and was unable to review this pull request. You can try again by re-requesting a review.

@kdy1 kdy1 enabled auto-merge (squash) December 29, 2025 07:58
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.

compress: Class property closures capture wrong instance values

2 participants