refactor(minifier): route all peephole mutations through typed helpers#23196
Conversation
How to use the Graphite Merge QueueAdd either label to this PR to merge it via the merge queue:
You must have a Graphite account in order to use the merge queue. Sign up using this link. An organization admin has enabled the Graphite Merge Queue in this repository. Please do not merge from GitHub as this will restart CI on PRs being processed by the merge queue. This stack of pull requests is managed by Graphite. Learn more about stacking. |
Merging this PR will not alter performance
Comparing Footnotes
|
a4fe763 to
8e9ace2
Compare
Merge activity
|
#23196) > Developed with AI assistance (Claude Code); reviewed, tested, and benchmarked by the contributor. ## Summary Replaces the ~190 manual `ctx.state.changed = true` writes scattered across `crates/oxc_minifier/src/peephole/` with typed mutation helpers on `MinifierTraverseCtx` (`replace_expression`, `replace_statement`, `replace_assignment_target_property`, `replace_property_key`, `replace_for_statement_left`, `drop_expression`, `drop_statement`, `drop_class_element`, `notice_change`). The mutation signal itself becomes a private `mutated: bool` on `MinifierState`, readable only via `take_mutated()` (read-and-reset in a single call) — the compiler now enforces that the fixed-point loop's signal can only be set by the helpers and only consumed by the loop driver. "Forgot to mark the loop dirty" — the bug pattern behind #22722 and #22552 — becomes structurally hard to write. The migration also carries the latent silent-mutation fixes surfaced by routing every mutation through a helper (missed `*slot = …` writes in `remove_unused_expression`, `convert_to_dotted_properties`, `minimize_statements`, and field-write bypass sites), plus idempotency gates in `try_fold_if` so the typed helpers don't block fixed-point convergence. This is stage 1 of 2 re-cutting the approach prototyped in #22736; the incremental scoping refresh stacks on top. ## Verification - `cargo test -p oxc_minifier` — 509 pass - `just minsize` — **bit-identical output** across the entire size-test corpus (this PR is a pure refactor) - `cargo coverage -- minifier` — conformance unchanged - clippy (all features/targets) clean - `allocs_minifier.snap`: small arena-only deltas (+0.02–0.08%) from helper call-site construction patterns; sys allocs unchanged
8e9ace2 to
09176f8
Compare
#23196) > Developed with AI assistance (Claude Code); reviewed, tested, and benchmarked by the contributor. ## Summary Replaces the ~190 manual `ctx.state.changed = true` writes scattered across `crates/oxc_minifier/src/peephole/` with typed mutation helpers on `MinifierTraverseCtx` (`replace_expression`, `replace_statement`, `replace_assignment_target_property`, `replace_property_key`, `replace_for_statement_left`, `drop_expression`, `drop_statement`, `drop_class_element`, `notice_change`). The mutation signal itself becomes a private `mutated: bool` on `MinifierState`, readable only via `take_mutated()` (read-and-reset in a single call) — the compiler now enforces that the fixed-point loop's signal can only be set by the helpers and only consumed by the loop driver. "Forgot to mark the loop dirty" — the bug pattern behind #22722 and #22552 — becomes structurally hard to write. The migration also carries the latent silent-mutation fixes surfaced by routing every mutation through a helper (missed `*slot = …` writes in `remove_unused_expression`, `convert_to_dotted_properties`, `minimize_statements`, and field-write bypass sites), plus idempotency gates in `try_fold_if` so the typed helpers don't block fixed-point convergence. This is stage 1 of 2 re-cutting the approach prototyped in #22736; the incremental scoping refresh stacks on top. ## Verification - `cargo test -p oxc_minifier` — 509 pass - `just minsize` — **bit-identical output** across the entire size-test corpus (this PR is a pure refactor) - `cargo coverage -- minifier` — conformance unchanged - clippy (all features/targets) clean - `allocs_minifier.snap`: small arena-only deltas (+0.02–0.08%) from helper call-site construction patterns; sys allocs unchanged

Summary
Replaces the ~190 manual
ctx.state.changed = truewrites scattered acrosscrates/oxc_minifier/src/peephole/with typed mutation helpers onMinifierTraverseCtx(replace_expression,replace_statement,replace_assignment_target_property,replace_property_key,replace_for_statement_left,drop_expression,drop_statement,drop_class_element,notice_change).The mutation signal itself becomes a private
mutated: boolonMinifierState, readable only viatake_mutated()(read-and-reset in a single call) — the compiler now enforces that the fixed-point loop's signal can only be set by the helpers and only consumed by the loop driver."Forgot to mark the loop dirty" — the bug pattern behind #22722 and #22552 — becomes structurally hard to write. The migration also carries the latent silent-mutation fixes surfaced by routing every mutation through a helper (missed
*slot = …writes inremove_unused_expression,convert_to_dotted_properties,minimize_statements, and field-write bypass sites), plus idempotency gates intry_fold_ifso the typed helpers don't block fixed-point convergence.This is stage 1 of 2 re-cutting the approach prototyped in #22736; the incremental scoping refresh stacks on top.
Verification
cargo test -p oxc_minifier— 509 passjust minsize— bit-identical output across the entire size-test corpus (this PR is a pure refactor)cargo coverage -- minifier— conformance unchangedallocs_minifier.snap: small arena-only deltas (+0.02–0.08%) from helper call-site construction patterns; sys allocs unchanged