Thanks to visit codestin.com
Credit goes to github.com

Skip to content

[compiler] Support logical assignment operators in BuildHIR#36733

Open
poteto wants to merge 2 commits into
react:mainfrom
poteto:lauren/fix-33315-logical-assignment
Open

[compiler] Support logical assignment operators in BuildHIR#36733
poteto wants to merge 2 commits into
react:mainfrom
poteto:lauren/fix-33315-logical-assignment

Conversation

@poteto

@poteto poteto commented Jun 10, 2026

Copy link
Copy Markdown
Collaborator

??=, &&=, and ||= were lowering todos in both compilers ("Handle ??= operators in AssignmentExpression"). Code using any logical assignment failed to compile.

Both compilers now lower a <op>= b as a <op> (a = b) using the exact value-block structure of the existing LogicalExpression lowering: the RHS and the store live only in the alternate block, so they evaluate only when the assignment is taken, and the emitted JS is the canonical desugar.

Member targets get single-evaluation semantics: the object and computed key are lowered once and, when they are not plain identifier references, copied into promoted const temporaries before the logical terminal. This is load-bearing: codegen re-emits unpromoted temporaries at each use site, so without the copy obj[key()] ||= rhs() would emit obj[key()] || (obj[key()] = rhs()) and call key() twice. The fixture proves single evaluation at runtime (calls: {key: 1}) along with the short-circuit semantics for all three operators.

Builds on #36394 by @raashish1601 (dispatch, desugar shape, target split), with the double-evaluation fix above and block construction restructured to match LogicalExpression lowering exactly so the TS and Rust pipelines stay in lockstep.

Related pre-existing issue, not addressed here: plain compound assignment has the same duplication bug on main today (obj[key()] += 1 evaluates the key twice). Same root cause class; will file separately.

Verification: TS snap 1806/1806, Rust snap 1806/1806, cargo workspace green, scoped TS-vs-Rust HIR parity harness green.

Closes #33315

@meta-cla meta-cla Bot added the CLA Signed label Jun 10, 2026
@poteto poteto marked this pull request as ready for review June 10, 2026 06:13
poteto and others added 2 commits June 17, 2026 01:01
Logical assignment operators (??=, &&=, ||=) currently bail out of
compilation as BuildHIR todos in both the TypeScript compiler and the
Rust port, so components using them are skipped entirely. Adds an
error.todo fixture documenting the three todo errors emitted today.

Repro for react#33315.
The logical assignment operators (??=, &&=, ||=) bailed out as BuildHIR
todos in both the TypeScript compiler and the Rust port. Lower `a ??= b`
as `a ?? (a = b)` (likewise for &&= and ||=), reusing the
logical-expression value-block lowering so that the right-hand side and
the store only evaluate when the assignment is taken. The target
reference is lowered exactly once, before the logical terminal; because
codegen re-emits unpromoted temporaries at each use site and the object
and computed key of member targets are referenced by both the load and
the conditional store, those temporaries are copied to promoted const
temporaries unless they are plain identifier references.

Desugaring approach adopted from react#36394 by Raashish Aggarwal, with the
block construction aligned to LogicalExpression lowering, single
evaluation of effectful member targets fixed, and the same lowering
ported to the Rust compiler.

Closes react#33315

Co-authored-by: Raashish Aggarwal <[email protected]>
@poteto poteto force-pushed the lauren/fix-33315-logical-assignment branch from 45d34a8 to 5b8ee65 Compare June 17, 2026 08:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Compiler Bug]: Todo: (BuildHIR::lowerExpression) Handle ??= operators in AssignmentExpression (164:164)

1 participant