The automated submodule bump #25261 regenerated `runtime.snap` on a loaded CI runner where two tests hit the global timeout, recording transient `timeout: global` failures (`expressions/arrow-function/name.js`, `function-code/10.4.3-1-13-s.js`) and dropping the pass count from 17306 to 17304. Both tests pass on a normal run, so monitor-oxc's Test262 drift check has failed on every run since ([example](https://github.com/oxc-project/monitor-oxc/actions/runs/31359248351/job/93364683855)).
This restores the snapshot to what `cargo coverage runtime` actually produces. Rather than regenerating locally (which could bake in this machine's own timeouts), the CI-reported diff was applied directly and verified byte-identical to CI's output (`git hash-object` matches the diff's `65e3fa9` blob).
Timeouts can get baked in again whenever an automated regen lands on a slow runner; retrying timed-out tests before recording them would close that hole and is left for a follow-up.
This PR was assisted by Claude.
#24463 moved the test262 pin from `de8e621c` to `d1d583db` but did not regenerate `tasks/coverage/snapshots/runtime.snap`, which still records the old sha. The runtime suite doesn't run in repo CI, so nothing caught it; monitor-oxc's Test262 job has been aborting on the snapshot sha guard ("Repository … is outdated for runtime.snap. Please run `just submodules`") on every run since 2026-07-13.
Two changes:
1. Regenerated the snapshot with `UPDATE_SNAPSHOT=1 cargo coverage runtime` against the pinned checkout: 17306/18277 (94.69%) passing, matching what monitor-oxc measures on main. The list changes are upstream test262 churn — two new `eval-code` global-function-init failures, and the async-arrow `forbidden-ext` block that no longer exists upstream.
2. Fixed the root cause of the staleness: the `update_submodules` workflow runs `just coverage`, whose default task skips the runtime suite, so `runtime.snap` was never regenerated on automated pin bumps. The workflow now runs `cargo coverage runtime` explicitly (it already sets up Node).
This PR was assisted by Claude.
Evaluating a class declaration can throw before any of its members matter. `class C extends C {}` reads its own name while it is still in the TDZ and always throws a ReferenceError. A heritage that is a `var`, or a lexical binding declared later, can be undefined or uninitialized at evaluation time and throws a TypeError. The minifier only checked for a literal arrow function as heritage, so removing an unused class could silently delete one of these guaranteed throws.
The removal check now unwraps parens and sequence wrappers before looking at the heritage, and keeps any class whose heritage identifier resolves to a class, `let`/`const`, or `var` binding. Declaration order cannot be proven in the middle of minification (transforms copy and move spans), so the rule is conservative on purpose. Function declarations, imports, and globals are initialized before any class can evaluate, so classes extending them can still be removed.
## Example
```js
var f = () => {};
class C extends f {}
```
Running this throws `TypeError: Class extends value ... is not a constructor`.
Before, the unused class was removed and the whole program minified to nothing, so the TypeError was gone. After, the output is unchanged and the throw is preserved:
```js
var f = () => {};
class C extends f {}
```
This fixes six test262 runtime failures that exist on main today (17279 -> 17285 positive passes): `in-extends-expression-grouped`, `in-extends-expression-assigned`, `superclass-arrow-function`, `prototype-getter`, `prototype-setter`, and `constructable-but-no-prototype`. The runtime suite executes the minified tests in node; the results were verified through monitor-oxc. Minified sizes are unchanged on every fixture.
Implemented with AI assistance (Claude Code); design, review, and verification driven by the author per the repo AI-usage policy.
## Summary
#18478 reduced the test262 runtime runner to a stub ("not yet implemented"), and since oxc's own CI never runs `cargo coverage runtime`, the transformer/minifier semantics coverage it provided has been dark — monitor-oxc's Test262 job (the only consumer) has been disabled since July 2025.
This restores execution on the simplified architecture: each eligible test262 case runs through codegen / transform / minify and executes in the Node runtime server, driven by rayon with blocking HTTP instead of the old tokio design. Skip lists and per-variant semantics are ported verbatim from the pre-#18478 runner.
- `main.rs` now loads `TestData` lazily, so `cargo coverage runtime` works with only the test262 fixtures checked out (which is how monitor-oxc CI invokes it).
- Execution is parallelized: one Node server per core with each rayon worker pinned to its own server, and the test262 harness is compiled once per distinct include list as a reusable `vm.Script` instead of re-parsed per request. Full suite: ~10s wall locally (~45s single-server).
- Results at test262 `de8e621c`: 17279/18277 positive tests pass (94.54%); `runtime.snap` is committed and byte-stable across repeated runs; clippy/fmt clean.
- monitor-oxc side: oxc-project/monitor-oxc#178 (must merge after this one).
Note: oxc CI still does not run the runtime suite, so `runtime.snap` can go stale and turn monitor-oxc's job red — the failure mode that led to the original "skip 262". Possible follow-ups: run it in conformance CI, or add a regression-only mode (fail on new failures, tolerate improvements).
Do not remove empty function calls if the function is async or generator or args can cause type error.
From test262:
```js
function fn({}) {}
assert.throws(TypeError, function() {
fn(null);
});
```
The new implementation port from [esbuild](https://github.com/evanw/esbuild/blob/df815ac27b84f8b34374c9182a93c94718f8a630/internal/js_parser/js_parser_lower.go#L355-L467), before from `Babel`.
Babel's transform implementation for the async method is incorrect because the async method should return a rejecting promise when it throws an error. Everything is good if the errors are thrown in the async method body, but the following case will throw an error in the parameters which causes the whole program crushed not a rejecting promise. So we should move the parameters to the inner generator function when the parameters could throw an error.
Input:
```js
class Cls {
// ReferenceError: Cannot access 'b' before initialization
async method(a = b, b = 0) {}
}
```
Before output
```js
class Cls {
method(a = b, b = 0) {
return babelHelpers.asyncToGenerator(function* () {})();
}
}
```
After output:
```js
class Cls {
method() {
// ReferenceError: Cannot access 'b' before initialization
return babelHelpers.asyncToGenerator(function* (a = b, b = 0) {}).apply(this, arguments);
}
}
```
No override tests because Babel doesn't cover this case.
Found a bunch of failed tests related to we don't use
`classPrivateSetter` and `classPrivateGetter` to transform private
getter and private setter. The simplest way is to add alternative helper
functions for these two. The reason we don't use I have explained in
#8132
```shell
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-add.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitand.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitor.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «15») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-bitxor.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «257») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-div.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «0.5») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-exp.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1000») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-lshift.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «96») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mod.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-mult.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «6») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-rshift.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-srshift.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «3») to be true
tasks/coverage/test262/test/language/expressions/compound-assignment/left-hand-side-private-reference-accessor-property-sub.js
transform error: Test262Error: The expression should evaluate to the result Expected SameValue(«undefined», «1») to be true
```