Skip to content

Preserve single evaluation of wrapped compound assignment targets - #65297

Merged
Wesley Wigham (weswigham) merged 4 commits into
mainfrom
copilot/fix-downlevel-emit-logical-assignment
Nov 4, 2026
Merged

Wesley Wigham (weswigham) merged 4 commits into
mainfrom
copilot/fix-downlevel-emit-logical-assignment

Conversation

Copilot AI commented Nov 3, 2026 •

Copy link
Copy Markdown
Contributor

Fixes #65287

Analysis

Type erasure wraps !, as, satisfies, and angle-bracket assertions in PartiallyEmittedExpression. Downlevel compound-assignment transforms miss the underlying member access, duplicating receiver or key evaluation.

obj[++key]! ||= 1;
// Before: obj[++key] || (obj[++key] = 1)
// After:  obj[_a = ++key] || (obj[_a] = 1)

Fix

  • Target recognition: Skip parentheses and type-erasure wrappers before lowering ||=, &&=, ??=, and **=.
  • super handling: Preserve the receiver directly while caching computed keys.
  • Regression coverage: Exercise wrapped property, element, and super targets across ES2015, ES2020, and ES2021.

Copilot Checklist

I successfully ran the applicable command at the end of my session, and it completed without error:

  • npx hereby validate
  • npx hereby validate --api (for TypeScript API changes)

@typescript-automation typescript-automation Bot added Author: Team For Milestone Bug PRs that fix a bug with a specific milestone labels Nov 3, 2026
@typescript-automation typescript-automation Bot added For Uncommitted Bug PR for untriaged, rejected, closed or missing bug and removed For Milestone Bug PRs that fix a bug with a specific milestone labels Nov 3, 2026
Copilot AI and others added 3 commits November 3, 2026 22:21
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Co-authored-by: RyanCavanaugh <6685088+RyanCavanaugh@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix downlevel emit evaluating member target twice Preserve single evaluation of wrapped compound assignment targets Nov 3, 2026
@RyanCavanaugh
Ryan Cavanaugh (RyanCavanaugh) marked this pull request as ready for review November 3, 2026 22:44
Copilot AI balanced review requested due to automatic review settings November 3, 2026 22:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

🟢 Approval recommended

No active review issues are identified for the changes preserving single evaluation of wrapped compound-assignment targets.

No open issues 🎉

What changed in this PR

Addresses #65287 in the native TypeScript compiler by preserving single evaluation of wrapped compound-assignment targets during downlevel emission.

Changes:

  • Recognize member targets beneath parentheses and type-erasure wrappers for logical and exponentiation assignments.
  • Preserve super directly during exponentiation lowering while caching computed keys.
  • Add regression coverage across ES2015, ES2020, and ES2021, and update affected conformance baselines.
File Description
tsc/​testdata/​tests/​cases/​compiler/​compoundAssignmentWithTypeOnlyExpressions.ts Tests wrapped property, element, and super targets.
tsc/​testdata/​baselines/​reference/​conformance/​compoundExponentiationAssignmentLHSIsValue.js Updates expected emit for value targets and super.
tsc/​testdata/​baselines/​reference/​conformance/​compoundExponentiationAssignmentLHSIsReference.js Records caching for parenthesized member targets.
tsc/​testdata/​baselines/​reference/​compiler/​compoundAssignmentWithTypeOnlyExpressions(target=es2021).js Records native compound-assignment emit after type erasure.
tsc/​testdata/​baselines/​reference/​compiler/​compoundAssignmentWithTypeOnlyExpressions(target=es2020).js Records corrected logical-assignment lowering.
tsc/​testdata/​baselines/​reference/​compiler/​compoundAssignmentWithTypeOnlyExpressions(target=es2015).js Records corrected logical and exponentiation lowering.
tsc/​internal/​transformers/​estransforms/​logicalassignment.go Unwraps type-erasure expressions before recognizing targets.
tsc/​internal/​transformers/​estransforms/​exponentiation.go Unwraps targets and avoids caching super as a value.

Review effort: Balanced

@weswigham
Wesley Wigham (weswigham) added this pull request to the merge queue Nov 3, 2026
Merged via the queue into main with commit e2bc2bc Nov 4, 2026
35 checks passed
@weswigham
Wesley Wigham (weswigham) deleted the copilot/fix-downlevel-emit-logical-assignment branch November 4, 2026 00:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Author: Team For Uncommitted Bug PR for untriaged, rejected, closed or missing bug

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Downlevel emit of ||=, &&=, ??= and **= evaluates a member target twice when it has !, as or satisfies

4 participants