Skip to content

fix(minifier): align class heritage removal with assumptions#24533

Merged
graphite-app[bot] merged 1 commit into
mainfrom
class-heritage-provable-init
Jul 20, 2026
Merged

fix(minifier): align class heritage removal with assumptions#24533
graphite-app[bot] merged 1 commit into
mainfrom
class-heritage-provable-init

Conversation

@Dunqing

@Dunqing Dunqing commented Jul 15, 2026

Copy link
Copy Markdown
Member

#24349 made unused-class removal conservatively keep every class whose heritage resolves to a class, lexical, or var binding. That preserves class-evaluation errors which the minifier assumptions explicitly allow optimizations to ignore, and it leaves (class extends Base {}); residue in Rolldown chunks after tree-shaking (rolldown#10274).

The minifier already documents both No TDZ Violation and No side effects from extending a class, and oxc_ecmascript explicitly ignores invalid-superclass errors so removable derived classes are not broadly deoptimized. Treat resolved identifier heritage like other pure reads while retaining the pre-existing literal-arrow exception, including its paren/sequence unwrap. Effects from evaluating the heritage expression, decorators, and effectful class elements remain observable.

The runtime harness already has minifier-only exclusions for unsupported inputs. Six Test262 fixtures covered by these assumptions are skipped only before the minifier variant, with the reason documented beside the list; codegen and transformer still execute, and runtime.snap remains unchanged.

Example

Input:

export var Base = class {};
export var Keep = class extends Base {};
var REMOVE = class extends Base {};

Before:

var Base = class {}, Keep = class extends Base {};
(class extends Base {});
export { Base, Keep };

After:

var Base = class {}, Keep = class extends Base {};
export { Base, Keep };

Verified with cargo test -p oxc_minifier, cargo coverage runtime, Clippy with warnings denied for oxc_minifier and oxc_coverage, just minsize, just allocs, formatting, and just ready. Minsize and runtime.snap are unchanged; the allocation snapshot records fewer allocations for kitchen-sink.tsx.

Implemented with AI assistance (Claude Code and OpenAI Codex). The contributor remains responsible for reviewing, understanding, and submitting the changes under the repository AI usage policy.

@github-actions github-actions Bot added the A-minifier Area - Minifier label Jul 15, 2026
@Dunqing Dunqing added the run-monitor-oxc Add to a PR to dispatch oxc-project/monitor-oxc CI against it label Jul 15, 2026
@oxc-guard

oxc-guard Bot commented Jul 15, 2026

Copy link
Copy Markdown
Contributor

@oxc-guard oxc-guard Bot removed the run-monitor-oxc Add to a PR to dispatch oxc-project/monitor-oxc CI against it label Jul 15, 2026
@codspeed-hq

codspeed-hq Bot commented Jul 15, 2026

Copy link
Copy Markdown

Merging this PR will not alter performance

✅ 57 untouched benchmarks
⏩ 19 skipped benchmarks1


Comparing class-heritage-provable-init (40369c7) with main (e750a82)

Open in CodSpeed

Footnotes

  1. 19 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.

@Dunqing
Dunqing force-pushed the class-heritage-provable-init branch from 7b2875c to f2bf78c Compare July 20, 2026 03:42
@Dunqing Dunqing changed the title feat(minifier): drop unused classes with provably initialized heritage fix(minifier): align class heritage removal with assumptions Jul 20, 2026
@Dunqing
Dunqing force-pushed the class-heritage-provable-init branch 2 times, most recently from dc81941 to 74eff31 Compare July 20, 2026 04:51
@Dunqing Dunqing added the run-monitor-oxc Add to a PR to dispatch oxc-project/monitor-oxc CI against it label Jul 20, 2026
@oxc-guard oxc-guard Bot removed the run-monitor-oxc Add to a PR to dispatch oxc-project/monitor-oxc CI against it label Jul 20, 2026
@Dunqing
Dunqing force-pushed the class-heritage-provable-init branch from 74eff31 to 40369c7 Compare July 20, 2026 09:41
@Dunqing
Dunqing marked this pull request as ready for review July 20, 2026 09:47
@Dunqing
Dunqing requested a review from overlookmotel as a code owner July 20, 2026 09:47
@Dunqing Dunqing added the 0-merge Merge with Graphite Merge Queue label Jul 20, 2026

Dunqing commented Jul 20, 2026

Copy link
Copy Markdown
Member Author

Merge activity

#24349 made unused-class removal conservatively keep every class whose heritage resolves to a class, lexical, or `var` binding. That preserves class-evaluation errors which the minifier assumptions explicitly allow optimizations to ignore, and it leaves `(class extends Base {});` residue in Rolldown chunks after tree-shaking ([rolldown#10274](rolldown/rolldown#10274)).

The minifier already documents both `No TDZ Violation` and `No side effects from extending a class`, and `oxc_ecmascript` explicitly ignores invalid-superclass errors so removable derived classes are not broadly deoptimized. Treat resolved identifier heritage like other pure reads while retaining the pre-existing literal-arrow exception, including its paren/sequence unwrap. Effects from evaluating the heritage expression, decorators, and effectful class elements remain observable.

The runtime harness already has minifier-only exclusions for unsupported inputs. Six Test262 fixtures covered by these assumptions are skipped only before the minifier variant, with the reason documented beside the list; codegen and transformer still execute, and `runtime.snap` remains unchanged.

## Example

Input:

```js
export var Base = class {};
export var Keep = class extends Base {};
var REMOVE = class extends Base {};
```

Before:

```js
var Base = class {}, Keep = class extends Base {};
(class extends Base {});
export { Base, Keep };
```

After:

```js
var Base = class {}, Keep = class extends Base {};
export { Base, Keep };
```

Verified with `cargo test -p oxc_minifier`, `cargo coverage runtime`, Clippy with warnings denied for `oxc_minifier` and `oxc_coverage`, `just minsize`, `just allocs`, formatting, and `just ready`. Minsize and `runtime.snap` are unchanged; the allocation snapshot records fewer allocations for `kitchen-sink.tsx`.

Implemented with AI assistance (Claude Code and OpenAI Codex). The contributor remains responsible for reviewing, understanding, and submitting the changes under the repository AI usage policy.
@graphite-app
graphite-app Bot force-pushed the class-heritage-provable-init branch from 40369c7 to 64c2241 Compare July 20, 2026 09:48
@graphite-app
graphite-app Bot merged commit 64c2241 into main Jul 20, 2026
29 checks passed
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Jul 20, 2026
@graphite-app
graphite-app Bot deleted the class-heritage-provable-init branch July 20, 2026 09:54
camc314 added a commit that referenced this pull request Jul 21, 2026
### 💥 BREAKING CHANGES

- 54cc121 ast: [**BREAKING**] Split `MetaProperty` into `ImportMeta` and
`NewTarget` (#24557) (camc314)

### 🚀 Features

- 4c71560 parser: More friendly error for spread element in dynamic
imports (#24705) (sapphi-red)
- 7b045cd minfier: Drop last break from last switch case (#24673)
(Armano)
- 7d3c178 minifier: Remove unreachable recursive functions (#24125)
(Dunqing)
- 94f99b3 ast: Allow `NONE` to be passed to AST builder methods where
`Option<ArenaVec>` is expected (#24629) (overlookmotel)
- 77230c5 ast: Accept arrays for `ArenaVec` params of AST builder
methods (#24621) (overlookmotel)
- f08b152 allocator: Implement `FromIn` for array to `Vec` conversion
(#24620) (overlookmotel)
- 2338c13 track-memory-allocations: Track heap deallocs, alloc bytes,
and peak growth (#24619) (Boshen)
- 7aa4739 syntax,transformer: Move JSX entity decoder to `oxc_syntax`
(#24617) (camc314)
- 2b097c4 str: Export `Str` as `ArenaStr` (#24604) (overlookmotel)
- 3acf4c1 minifier: Expand switch optimiation to remove empty cases
(#24520) (Armano)
- 129b759 parser: Improve diagnostics for unparenthesized LHS on
exponential expr (#24569) (camc314)
- 4d0c601 minifier: Fold arithmetic over undefined and null operands
(#24485) (Dunqing)
- 91541dd minifier: Drop empty switch statements  (#24527) (Armano)
- d05224d ast_visit: Generate VisitJs visitor that skips TypeScript
type-space (#24499) (Boshen)
- 3d22307 parser: Add `ParseOptions::enable_ident_hashes` (#24491)
(Boshen)

### 🐛 Bug Fixes

- 64c2241 minifier: Align class heritage removal with assumptions
(#24533) (Dunqing)
- 48b59f4 parser: Span ambient generator diagnostics (#24711) (camc314)
- e750a82 ecmascript: Fix false negative for may_have_side_effects on
dynamic property access (#24709) (sapphi-red)
- f145d73 minifier: Guard reordered identifier reads (#24698) (Dunqing)
- a2ef382 isolated-declarations: Reject `window.Symbol` as global symbol
reference (#24689) (camc314)
- b1bcf72 minifier: Invalidate facts for redeclared bindings (#24658)
(Dunqing)
- 921b834 minifier: Don't treat a conditionally-assigned var as
write-once (#24650) (Dunqing)
- 061af1f minifier: Avoid stale pure function summaries (#24636)
(Dunqing)
- 40c2f43 allocator: `Vec::from_array_in` do not allocate zero-length
array (#24628) (overlookmotel)
- 70994ae codegen: Preserve comments before expression operands (#24510)
(Dunqing)
- 7b4baff parser: Reject new import member access (#23459) (camc314)
- 128b385 minifier: Clippy warning with no-debug-assertions (#24547)
(camc314)
- 8421feb parser: Use first `as` span for imported name (#24537)
(leaysgur)
- c517aa0 parser: Reject invalid accessor assertions (#24504) (camc314)

### ⚡ Performance

- 884d9eb parser: Pre-size cover-grammar assignment target buffers
(#24683) (Boshen)
- d3f07a0 diagnostics: Box OxcDiagnosticInner to reduce binary size
(#24665) (Boshen)
- bcc9de0 parser: Defer diagnostic creation until parse exit (#24663)
(Boshen)
- c35d8ab allocator: Mark `ReplaceWith` panic path cold (#24515)
(camc314)
- ba65790 semantic, allocator: Branchless `clone_in` for semantic IDs
(#24564) (overlookmotel)
- 747feec parser: Build AST nodes with the AST builder instead of
cloning (#24540) (Boshen)
- ba35a0d react_compiler: Use IndexVec for dense id-keyed maps (#24549)
(Boshen)
- b685062 react_compiler: Keep small hot-path collections inline
(#24514) (Marius Schulz)
- a149e95 transformer: Outline rare expression exits (#24512) (camc314)
- 7808a6e react_compiler: Make aliasing effects cheap to intern and
clone (#24506) (Marius Schulz)
- 3a36f2a react_compiler: Store AbstractValue reasons as a u16 bitmask
(#24480) (Boshen)
- 1c96753 react_compiler: Use FxHashMap for the lookup-only aliasing
node map (#24490) (Boshen)

Co-authored-by: Cameron <[email protected]>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-minifier Area - Minifier

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant