#12309·swc

es/minifier: class effect extraction loses implicit strict mode

Author: kdy1Created Sep 9, 2026Updated Sep 9, 2026
LabelsC-bugLabor0

Describe the bug

extract_class_side_effect moves a static initializer expression into its surrounding script. Class evaluation is strict even in sloppy code; the current ClassEffectVisitor guards lexical class dependencies but not strict-mode-sensitive operations. An unresolved assignment changes from ReferenceError to creating a global.

Input code

javascript
try { (class {static x=(undeclared_audit=1)});console.log("no error") } catch(e){console.log(e.name)}

Config

Options used by the exact-source reproduction:

json
{
  "compress": {
    "defaults": false,
    "side_effects": true
  },
  "mangle": false,
  "module": false
}

Link to the code that reproduces this issue

Portable input and settings in SWC Playground

SWC Info output

Source build of swc_ecma_minifier 61.0.5, commit 246e6156ca14eaa07243ac8d9aa994c91c95cf3d, macOS arm64, Rust 1.96.0-nightly (f5eca4fcf 2026-04-09), Node v20.20.2.

The observed checkout and freshly fetched authoritative origin/main are the same commit. Fetch: git fetch --no-tags origin main, 2026-09-09T03:15:52Z, repository swc-project/swc. Reproduction was performed in a separate checkout of that fetched commit. Thus the cause remains on the default branch, not only in an older release.

For minify cases, the source harness follows the repository example: parse, resolve bindings, convert Terser compressor options, call optimize, apply fixer, emit, and execute original/output separately. Script-only behavior uses Script parsing. The playground carries portable source/settings; its published version is not evidence that the release matches the pinned source build. No implementation change was applied.

Expected behavior

Exit 0; stdout:

ReferenceError

Actual behavior

javascript
try{undeclared_audit=1;console.log("no error")}catch(e){console.log(e.name)}

Exit 0; stdout:

no error

Version

swc_ecma_minifier 61.0.5, 246e6156ca14eaa07243ac8d9aa994c91c95cf3d (also freshly fetched main).

Additional context

Responsible code: compress/optimize/util.rs:173.

Parse as Script (module:false). The original contains no TDZ access, property setter, or modified builtin; the distinction is the mandatory strictness of class code.

Proposed Scope

Retain the class when extracting its evaluated expressions would lose implicit strict-mode semantics. Conservatively decline extraction of strict-mode-sensitive assignments/deletions in a sloppy surrounding context; preserve safe extraction in an already strict context and receiver-independent expressions.

Limit the change to this semantic boundary and its regression coverage. No API expansion, dependency update, migration, deployment, or feature-flag rollout is required. Preserve the documented minifier assumptions; the reproduction does not require overriding builtin implementations.

Acceptance Criteria and Test Scenarios

  • The primary script must print ReferenceError and must not create undeclared_audit.
  • Add an outer use strict directive and retain the existing ReferenceError behavior.
  • Cover a static block and static private-field initializer with the same unresolved assignment.
  • A static initializer containing an ordinary observable function call preserves its call count/order.
  • Add regression coverage in the existing SWC-owned fixture/execution suites under crates/swc_ecma_minifier/tests/fixture/issues, or the existing tests/eval.rs API harness for the Evaluator case. Check exact execution/return values and valid generated syntax, not only snapshots.
  • Initialize submodules, update fixture expectations only as needed, and rerun cargo test -p swc_ecma_minifier without UPDATE. Preserve passing controls above. Keep regression comments in English.

Duplicate search

No same-root open duplicate was found in bounded searches including "class" "strict" "minify" and related minifier terms. Similar issues were evaluated by root cause and transformation boundary.

Out of Scope

Unrelated rewrites, new user options, implementing other audit findings, and changing semantic assumptions.


This is a message for readers, not the author of this issue.

Please read no +1 before leaving a comment.