Skip to content

feat(minifier): support property_write_side_effects option to drop unused property assignments#20773

Merged
graphite-app[bot] merged 1 commit intomainfrom
feat/minifier-property-write-side-effects-v2
Apr 9, 2026
Merged

feat(minifier): support property_write_side_effects option to drop unused property assignments#20773
graphite-app[bot] merged 1 commit intomainfrom
feat/minifier-property-write-side-effects-v2

Conversation

@Dunqing
Copy link
Copy Markdown
Member

@Dunqing Dunqing commented Mar 26, 2026

Summary

Add property_write_side_effects option to TreeShakeOptions (default true). When set to false, property assignments like A.from = () => {} are considered side-effect-free, enabling the minifier to drop declarations and fresh value bindings with property assignments when unused.

Examples

// Function declaration + property assignments → eliminated
function A() {}
A.from = () => {}
A.to = () => {}
// Output: (empty)

// Class declaration + property assignment → eliminated
class A {}
A.foo = 1
// Output: (empty)

// Const variable with arrow function → eliminated
const A = () => {}
A.foo = 1
// Output: (empty)

// Const variable with object literal → eliminated
const B = {}
B.foo = 1
// Output: (empty)

// Const variable with function expression → eliminated
const C = function() {}
C.foo = 1
// Output: (empty)

How it works

  1. Wires the existing property_write_side_effects from oxc_ecmascript's MayHaveSideEffectsContext through the minifier's compress options
  2. For member expression assignments, checks may_have_side_effects() then is_member_assign_to_unused_binding()
  3. is_member_assign_to_unused_binding verifies:
    • Single-level member expression only (A.foo, not a.b.c)
    • All references to the symbol have the MemberWriteTarget flag (from parent PR)
    • Symbol creates a fresh value (is_fresh_value) and is not exported
  4. Fixed-point loop handles cascading: first pass drops assignments, exit_program cleans up references, second pass drops declarations

Fresh value detection

A symbol is considered "fresh" (cannot alias another binding and property writes are side-effect-free) if it is:

  • A function declaration
  • A class declaration without static setters, static accessor properties, or static property definitions with values
  • A variable initialized with an array/arrow function/function expression literal
  • A variable initialized with an object literal without setter/getter properties or property values containing setters/getters
  • A variable initialized with a class expression (same rules as class declarations above)

Non-fresh values (e.g. const b = a) are conservatively preserved to prevent breaking aliased references.

Setter/getter detection (addresses review feedback)

Following how esbuild, Terser, Rollup, and SWC handle setter cases — all tools preserve property writes when setters are visible in the AST:

  • Static setter methods: class A { static set foo(v) { ... } } → not fresh
  • Static accessor properties: class A { static accessor foo = 0 } → not fresh (auto-generates getter+setter)
  • Static property definitions with values: class A { static b = 0 } → not fresh (matches SWC's conservative approach)
  • Static property values containing setters/getters: class A { static b = { set x(v) { ... } } } → not fresh
  • Object literal setters/getters: { set foo(v) { ... } } or { get foo() { ... } } → not fresh
  • Nested setters/getters in object property values: { bar: { set x(v) { ... } } } → not fresh
  • Non-static setters are fine: class A { set foo(v) { ... } } → fresh (instance setters don't affect class-level property writes)

Limitations

Only single-level member expressions are supported (A.foo, not a.b.c). Deep nested assignments like a.b.c = 1 are always preserved because intermediate properties could alias external objects:

const exported = {};
const a = { b: exported };
a.b.c = 1; // writes to exported.c — unsafe to drop!
export { exported };

Supporting deeper nesting would require full object graph tracking (like Rollup's ObjectEntity model), which is a much larger effort for marginal gain.

Safety guards

Addresses concerns raised in PR #20730 review and comment:

  • Aliases: const b = a; b.add = 1; export { a } → kept (not fresh, could mutate exported a through alias)
  • Chained access: const b = { a }; b.a.add = 1; export { a } → kept (only single-level member expressions allowed)
  • Exported symbols: export function A() {} A.foo = 1; → kept (observable by importers)
  • Other reads: function A() {} A.foo = 1; console.log(A) → kept (symbol has non-member-write references)
  • Side-effectful RHS: function A() {} A.foo = sideEffect() → kept (may_have_side_effects returns true)
  • Globals: globalObj.foo = 1 → kept (no local binding)
  • Script mode top-level: top-level bindings in script mode are kept (they're globals visible to other scripts)
  • Setters: class A { static set foo(v) { ... } } A.foo = 1 → kept (setter triggers side effects)
  • Static properties: class A { static b = 0 } A.b = 1 → kept (matches SWC's conservative approach)

Comparison with other tools

Tool Approach Option needed?
Rollup Structural aliasing analysis — tracks object identity through LocalVariable.isReassigned + ObjectEntity setter detection. Drops A.foo = 1 automatically when A is a local unreassigned object with no setters. No (always active)
Rolldown Adds explicit treeshake.propertyWriteSideEffects option (default 'always'). Not in upstream Rollup. Yes
Terser Checks is_constant_expression on the base object after unwrapping property chain. If the base is constant within scope, drops the assignment. No (always active, but less precise)
esbuild All property assignments always preserved. Rationale: Object.defineProperty could install prototype setters. Only escape hatch is /* @__PURE__ */ IIFE wrapping. No option available
SWC may_have_side_effects returns true for all assignments unconditionally. Classes with static property definitions are conservatively preserved. No option available
Oxc (this PR) Fresh value tracking (is_fresh_value) + MemberWriteTarget reference flags + explicit option. Closest to Rollup's aliasing analysis but gated behind an option like Rolldown. Yes (property_write_side_effects: false)

Closes #14207

Test plan

  • 20 test cases covering all safety scenarios including setter/getter edge cases
  • All minifier tests pass (476/476)
  • No minsize regressions
  • Clippy clean

🤖 Generated with Claude Code

Copy link
Copy Markdown
Member Author

Dunqing commented Mar 26, 2026


How to use the Graphite Merge Queue

Add either label to this PR to merge it via the merge queue:

  • 0-merge - adds this PR to the back of the merge queue
  • hotfix - for urgent changes, fast-track this PR to the front of 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.

@github-actions github-actions Bot added A-minifier Area - Minifier C-enhancement Category - New feature or request labels Mar 26, 2026
@codspeed-hq
Copy link
Copy Markdown

codspeed-hq Bot commented Mar 26, 2026

Merging this PR will degrade performance by 3.43%

❌ 1 regressed benchmark
✅ 43 untouched benchmarks
⏩ 7 skipped benchmarks1

⚠️ Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Mode Benchmark BASE HEAD Efficiency
Simulation minifier[react.development.js] 2.7 ms 2.8 ms -3.43%

Comparing feat/minifier-property-write-side-effects-v2 (f6ef890) with main (f21d3aa)

Open in CodSpeed

Footnotes

  1. 7 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 feat/semantic-member-write-target-flag branch from ae2c858 to 075f2cd Compare March 26, 2026 13:59
@Dunqing Dunqing force-pushed the feat/minifier-property-write-side-effects-v2 branch 2 times, most recently from 8b2ca65 to 3ade183 Compare March 30, 2026 07:50
@github-actions github-actions Bot added the A-semantic Area - Semantic label Mar 30, 2026
@Dunqing Dunqing force-pushed the feat/semantic-member-write-target-flag branch from 2ffb46b to abd48a1 Compare March 30, 2026 09:52
@Dunqing Dunqing force-pushed the feat/minifier-property-write-side-effects-v2 branch from 3ade183 to 681dcf2 Compare March 30, 2026 09:52
@graphite-app graphite-app Bot changed the base branch from feat/semantic-member-write-target-flag to graphite-base/20773 April 7, 2026 06:11
graphite-app Bot pushed a commit that referenced this pull request Apr 7, 2026
)

## Summary

Add a new `MemberWriteTarget` bit to `ReferenceFlags` ~~Store member write target references in a separate `FxHashSet<ReferenceId>` on `Semantic` rather than adding a flag to `ReferenceFlags`.~~

This marks identifier references read as the object of a member expression in a simple assignment target position (e.g., `A` in `A.foo = 1`).

- Set during `visit_member_expression` when flags indicate write-only context (simple `=`, not compound `+=` or update `++`)
- Stored in `Semantic::member_write_references` (`FxHashSet<ReferenceId>`)
- Queryable via `Semantic::is_member_write_reference(reference_id)` and `Semantic::member_write_references()`
- Does not affect existing `ReferenceFlags` — no changes to the shared bitflags type

## Motivation

Distinguishing "reads that exist only to serve a property write" from "real reads" is broadly useful:

### Minifier: dead code elimination of property-write-only symbols

```js
function A() {}
A.from = () => {}  // A's only reference is a member write target
// → both can be eliminated when property_write_side_effects: false
```

Without this info, the minifier sees `A` as "referenced" and cannot remove the function declaration. With it, the minifier knows all of `A`'s reads are property-write targets and can safely drop them. (See stacked PR #20773 — will be updated to use the new API in a follow-up)

### Linter: `no_unused_vars` improvement

```js
const config = {};
config.debug = true;
config.verbose = false;
// config is never read — only mutated via property writes
```

Currently `config` is considered "used" because `config.debug = ...` creates a read reference. With member write target tracking, `no_unused_vars` could detect that `config`'s only reads are property-write targets and report it as unused.

### Linter: simplify `no_param_reassign` property detection

`no_param_reassign` has a complex `is_modifying_property()` function that manually walks the ancestor chain to detect property modifications like `param.foo = 1`. With member write target tracking, this can be checked directly on the reference.

### Rolldown: replace `MemberExprIsWrite` traversal state

Rolldown already maintains its own [`MemberExprIsWrite` flag](https://github.com/rolldown/rolldown/blob/eec7d7320cc991e1efd5ed8264d02c6889a223c3/crates/rolldown/src/ast_scanner/mod.rs#L130-L131) as local traversal state in the AST scanner to [detect member expressions in write context](https://github.com/rolldown/rolldown/blob/eec7d7320cc991e1efd5ed8264d02c6889a223c3/crates/rolldown/src/ast_scanner/impl_visit.rs#L55-L73). Having this on `Semantic` means Rolldown can consume it directly instead of re-detecting it during scanning. There's also a [TODO in Rolldown's treeshake options](https://github.com/rolldown/rolldown/blob/main/crates/rolldown_common/src/inner_bundler_options/types/treeshake.rs#L255-L259) to wire `property_write_side_effects` to oxc_minifier — our stacked PR #20773 provides that.

### General: escape analysis for local objects

Any analysis that needs to know "is this object only mutated locally, never passed elsewhere?" benefits from knowing which reads are purely for property writes vs. reads that pass the value to other functions.

## Test plan

- [x] Semantic snapshot tests updated
- [x] Conformance snapshots updated
- [x] Clippy clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@Dunqing Dunqing force-pushed the graphite-base/20773 branch from abd48a1 to 75663c0 Compare April 7, 2026 08:59
@Dunqing Dunqing force-pushed the feat/minifier-property-write-side-effects-v2 branch from 681dcf2 to 232df97 Compare April 7, 2026 08:59
@Dunqing Dunqing changed the base branch from graphite-base/20773 to main April 7, 2026 08:59
@github-actions github-actions Bot added the A-allocator Area - Allocator label Apr 8, 2026
@Dunqing Dunqing force-pushed the feat/minifier-property-write-side-effects-v2 branch from d8b3872 to 498a43b Compare April 8, 2026 02:51
@Dunqing
Copy link
Copy Markdown
Member Author

Dunqing commented Apr 8, 2026

Hi @sapphi-red, I reimplemented #20730 in this PR and solved two cases you mentioned in that. Please take a look again. Thank you!

@Dunqing Dunqing requested review from Boshen and sapphi-red April 8, 2026 02:59
@Dunqing Dunqing removed the A-allocator Area - Allocator label Apr 8, 2026
@Dunqing Dunqing marked this pull request as ready for review April 8, 2026 02:59
@sapphi-red
Copy link
Copy Markdown
Member

  • Side-effectful RHS: function A() {} A.foo = sideEffect() → kept (may_have_side_effects returns true)

We only need to keep the sideEffect() for this case.

SWC may_have_side_effects returns true for all assignments unconditionally. No optimization for property writes.

I think this is incorrect. SWC does remove them (playground).

Comment thread crates/oxc_minifier/tests/peephole/remove_unused_expression.rs
Comment thread crates/oxc_minifier/tests/peephole/remove_unused_expression.rs
@Dunqing Dunqing force-pushed the feat/minifier-property-write-side-effects-v2 branch 3 times, most recently from ea4c121 to b2b1685 Compare April 8, 2026 08:53
@Dunqing
Copy link
Copy Markdown
Member Author

Dunqing commented Apr 8, 2026

SWC may_have_side_effects returns true for all assignments unconditionally. No optimization for property writes.

I think this is incorrect. SWC does remove them (playground).

You are right, our implementation now matches the SWC implementation

@Dunqing Dunqing force-pushed the feat/minifier-property-write-side-effects-v2 branch from b2b1685 to b744bb4 Compare April 8, 2026 09:21
Comment thread crates/oxc_minifier/tests/peephole/remove_unused_expression.rs
@Dunqing Dunqing force-pushed the feat/minifier-property-write-side-effects-v2 branch 2 times, most recently from 7438f81 to bfc48ff Compare April 8, 2026 13:38
Comment thread crates/oxc_minifier/src/peephole/remove_unused_expression.rs Outdated
Comment thread crates/oxc_minifier/src/peephole/remove_unused_expression.rs Outdated
Comment thread crates/oxc_minifier/tests/peephole/remove_unused_expression.rs
Copy link
Copy Markdown
Member

@sapphi-red sapphi-red left a comment

Choose a reason for hiding this comment

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

LGTM

I think we should test this option out in many places after we merge this and is released in Rolldown / Vite.

Copy link
Copy Markdown
Member Author

Dunqing commented Apr 9, 2026

Merge activity

…unused property assignments (#20773)

## Summary

Add `property_write_side_effects` option to `TreeShakeOptions` (default `true`). When set to `false`, property assignments like `A.from = () => {}` are considered side-effect-free, enabling the minifier to drop declarations and fresh value bindings with property assignments when unused.

### Examples

```js
// Function declaration + property assignments → eliminated
function A() {}
A.from = () => {}
A.to = () => {}
// Output: (empty)

// Class declaration + property assignment → eliminated
class A {}
A.foo = 1
// Output: (empty)

// Const variable with arrow function → eliminated
const A = () => {}
A.foo = 1
// Output: (empty)

// Const variable with object literal → eliminated
const B = {}
B.foo = 1
// Output: (empty)

// Const variable with function expression → eliminated
const C = function() {}
C.foo = 1
// Output: (empty)
```

### How it works

1. Wires the existing `property_write_side_effects` from `oxc_ecmascript`'s `MayHaveSideEffectsContext` through the minifier's compress options
2. For member expression assignments, checks `may_have_side_effects()` then `is_member_assign_to_unused_binding()`
3. `is_member_assign_to_unused_binding` verifies:
   - Single-level member expression only (`A.foo`, not `a.b.c`)
   - All references to the symbol have the `MemberWriteTarget` flag (from parent PR)
   - Symbol creates a fresh value (`is_fresh_value`) and is not exported
4. Fixed-point loop handles cascading: first pass drops assignments, `exit_program` cleans up references, second pass drops declarations

### Fresh value detection

A symbol is considered "fresh" (cannot alias another binding and property writes are side-effect-free) if it is:
- A **function declaration**
- A **class declaration** without static setters, static accessor properties, or static property definitions with values
- A variable initialized with an **array/arrow function/function expression** literal
- A variable initialized with an **object literal** without setter/getter properties or property values containing setters/getters
- A variable initialized with a **class expression** (same rules as class declarations above)

Non-fresh values (e.g. `const b = a`) are conservatively preserved to prevent breaking aliased references.

#### Setter/getter detection (addresses review feedback)

Following how esbuild, Terser, Rollup, and SWC handle setter cases — all tools preserve property writes when setters are visible in the AST:

- **Static setter methods**: `class A { static set foo(v) { ... } }` → not fresh
- **Static accessor properties**: `class A { static accessor foo = 0 }` → not fresh (auto-generates getter+setter)
- **Static property definitions with values**: `class A { static b = 0 }` → not fresh (matches SWC's conservative approach)
- **Static property values containing setters/getters**: `class A { static b = { set x(v) { ... } } }` → not fresh
- **Object literal setters/getters**: `{ set foo(v) { ... } }` or `{ get foo() { ... } }` → not fresh
- **Nested setters/getters in object property values**: `{ bar: { set x(v) { ... } } }` → not fresh
- **Non-static setters are fine**: `class A { set foo(v) { ... } }` → fresh (instance setters don't affect class-level property writes)

### Limitations

**Only single-level member expressions are supported** (`A.foo`, not `a.b.c`). Deep nested assignments like `a.b.c = 1` are always preserved because intermediate properties could alias external objects:

```js
const exported = {};
const a = { b: exported };
a.b.c = 1; // writes to exported.c — unsafe to drop!
export { exported };
```

Supporting deeper nesting would require full object graph tracking (like Rollup's `ObjectEntity` model), which is a much larger effort for marginal gain.

### Safety guards

Addresses concerns raised in [PR #20730 review](#20730 (review)) and [comment](#20730 (comment)):

- **Aliases**: `const b = a; b.add = 1; export { a }` → kept (not fresh, could mutate exported `a` through alias)
- **Chained access**: `const b = { a }; b.a.add = 1; export { a }` → kept (only single-level member expressions allowed)
- **Exported symbols**: `export function A() {} A.foo = 1;` → kept (observable by importers)
- **Other reads**: `function A() {} A.foo = 1; console.log(A)` → kept (symbol has non-member-write references)
- **Side-effectful RHS**: `function A() {} A.foo = sideEffect()` → kept (`may_have_side_effects` returns true)
- **Globals**: `globalObj.foo = 1` → kept (no local binding)
- **Script mode top-level**: top-level bindings in script mode are kept (they're globals visible to other scripts)
- **Setters**: `class A { static set foo(v) { ... } } A.foo = 1` → kept (setter triggers side effects)
- **Static properties**: `class A { static b = 0 } A.b = 1` → kept (matches SWC's conservative approach)

### Comparison with other tools

| Tool | Approach | Option needed? |
|------|----------|---------------|
| **Rollup** | Structural aliasing analysis — tracks object identity through `LocalVariable.isReassigned` + `ObjectEntity` setter detection. Drops `A.foo = 1` automatically when `A` is a local unreassigned object with no setters. | No (always active) |
| **Rolldown** | Adds explicit [`treeshake.propertyWriteSideEffects`](https://rolldown.rs/reference/InputOptions.treeshake#propertywritesideeffects) option (default `'always'`). Not in upstream Rollup. | Yes |
| **Terser** | Checks `is_constant_expression` on the base object after unwrapping property chain. If the base is constant within scope, drops the assignment. | No (always active, but less precise) |
| **esbuild** | All property assignments always preserved. Rationale: `Object.defineProperty` could install prototype setters. Only escape hatch is `/* @__PURE__ */` IIFE wrapping. | No option available |
| **SWC** | `may_have_side_effects` returns `true` for all assignments unconditionally. Classes with static property definitions are conservatively preserved. | No option available |
| **Oxc (this PR)** | Fresh value tracking (`is_fresh_value`) + `MemberWriteTarget` reference flags + explicit option. Closest to Rollup's aliasing analysis but gated behind an option like Rolldown. | Yes (`property_write_side_effects: false`) |

Closes #14207

## Test plan

- [x] 20 test cases covering all safety scenarios including setter/getter edge cases
- [x] All minifier tests pass (476/476)
- [x] No minsize regressions
- [x] Clippy clean

🤖 Generated with [Claude Code](https://claude.com/claude-code)
@graphite-app graphite-app Bot force-pushed the feat/minifier-property-write-side-effects-v2 branch from f6ef890 to f134e24 Compare April 9, 2026 11:13
@graphite-app graphite-app Bot merged commit f134e24 into main Apr 9, 2026
26 checks passed
@graphite-app graphite-app Bot removed the 0-merge Merge with Graphite Merge Queue label Apr 9, 2026
@graphite-app graphite-app Bot deleted the feat/minifier-property-write-side-effects-v2 branch April 9, 2026 11:18
camc314 pushed a commit that referenced this pull request Apr 13, 2026
### 💥 BREAKING CHANGES

- 36cdc31 str: [**BREAKING**] Remove identity `FromIn` impl for `Ident`
(#21251) (overlookmotel)
- 382958a span: [**BREAKING**] Remove re-exports of string types from
`oxc_span` crate (#21246) (overlookmotel)
- c4aedfa str: [**BREAKING**] Add `static_ident!` macro (#21245)
(overlookmotel)

### 🚀 Features

- e7e1aea transformer/typescript: Add `optimize_enums` option for
regular enum inlining (#20539) (Dunqing)
- 679f57f transformer/typescript: Implement const enum inlining and
declaration removal (#20508) (Dunqing)
- 6dd061c semantic: Extend `MemberWriteTarget` to cover all property
modification patterns (#21205) (Dunqing)
- f134e24 minifier: Support `property_write_side_effects` option to drop
unused property assignments (#20773) (Dunqing)
- 75663c0 semantic: Add enum member value evaluation for const enum
support (#20602) (Dunqing)
- 3cfe8ed semantic: Add `MemberWriteTarget` flag to `ReferenceFlags`
(#20772) (Dunqing)

### 🐛 Bug Fixes

- af1a586 transformer/class-properties: Use correct property name when
converting parameter properties (#21268) (Amal Jossy)
- b43250a allocator: Move allocation tracking into `Bump` (#21342)
(overlookmotel)
- 36f505f allocator: `StringBuilder` use `Allocator::alloc_layout`
(#21340) (overlookmotel)
- 7a08a6f allocator: Fix allocation counting in
`Allocator::alloc_concat_strs_array` (#21336) (overlookmotel)
- 2338e28 ecmascript: Treat `this` as potentially having side effects
(#21297) (sapphi-red)
- bd8bd39 allocator: Remove unsafe hacks from `from_raw_parts` methods
(#21283) (overlookmotel)
- 8f4c340 allocator: Remove dangerous pointer const to mut cast (#21279)
(overlookmotel)
- aa9259f parser: Add missing error code for optional param diagnostic
(#21258) (camc314)
- 04b3c2f str: Fix unsound casting const pointers to mut pointers
(#21242) (overlookmotel)
- ceadf6c str: Make `Ident::from_raw` an unsafe function (#21241)
(overlookmotel)
- eab13b3 transformer/decorators: Avoid accessor storage name collisions
(#21106) (Dunqing)
- 07e8a30 transformer/react-refresh: Handle parenthesized variable
initializers (#21047) (camc314)

### ⚡ Performance

- c3ca6f6 allocator: `StringBuilder::from_strs_array_in` check for 0
length earlier (#21338) (overlookmotel)
- c2422bb allocator: `Allocator::alloc_concat_strs_array` check for 0
length earlier (#21337) (overlookmotel)
- 04b0fdc allocator: Mark `Allocator::alloc_layout` as
`#[inline(always)]` (#21335) (overlookmotel)
- 17aee9e allocator: Use `offset_from_unsigned` in
`ChunkFooter::as_raw_parts` (#21280) (overlookmotel)
- 61adedd minifier: Fix O(n²) perf on very many var decls (#21062)
(Gunnlaugur Thor Briem)
- addcd02 napi/parser, linter/plugins: Raw transfer deserializer for
`Vec`s use shift instead of multiply where possible (#21142)
(overlookmotel)
- 3068ded napi/parser, linter/plugins: Shift before add when calculating
positions in raw transfer deserializer (#21141) (overlookmotel)
- eb400b8 napi/parser, linter/plugins: Remove `uint32` buffer view
(#21140) (overlookmotel)
- 2675085 napi/parser: Lazy deserialization use only `Int32Array`
(#21139) (overlookmotel)
- 5b35a53 napi/parser: Deserializing tokens use only `int32` array
(#21138) (overlookmotel)
- f163d10 parser: Tokens raw deserialization use `Int32Array` (#21137)
(overlookmotel)
- 7a86613 linter/plugins: Use `Int32Array`s for tokens and comments
buffers (#21136) (overlookmotel)
- 8c51121 napi/parser, linter/plugins: Raw transfer deserialize `Span`
fields as `i32`s (#21135) (overlookmotel)
- bc1bcdd napi/parser, linter/plugins: Inline trivial raw transfer field
deserializers into node object definitions (#21134) (overlookmotel)
- c0278ab napi/parser, linter/plugins: Use `Int32Array` in raw transfer
deserializer (#21132) (overlookmotel)
- 43482c7 linter/plugins: Use `>>` not `>>>` in binary search loops
(#21129) (overlookmotel)

### 📚 Documentation

- f5e1845 allocator: Upgrade headers in doc comments for `Bump` (#21263)
(overlookmotel)
- 2870174 allocator: Upper case `SAFETY` in comments (#21253)
(overlookmotel)
- 01bc269 str: Reformat `Ident` doc comments (#21240) (overlookmotel)
- dd47359 allocator: Add doc comments for panics and errors (#21230)
(overlookmotel)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

A-minifier Area - Minifier A-semantic Area - Semantic C-enhancement Category - New feature or request

Projects

None yet

Development

Successfully merging this pull request may close these issues.

minifier: drop constructed functions/objects

2 participants