Visitar URL original
fix(transform-spread): copy constant array when later elements have side effects by hoanle0126 · Pull Request #18613 · babel/babel · GitHub
Skip to content

fix(transform-spread): copy constant array when later elements have side effects - #18613

Open
hoanle0126 wants to merge 2 commits into
babel:mainfrom
hoanle0126:fix/spread-mutated-array-18531
Open

hoanle0126 wants to merge 2 commits into
babel:mainfrom
hoanle0126:fix/spread-mutated-array-18531

Conversation

@hoanle0126

@hoanle0126 hoanle0126 commented Nov 13, 2026 •

Copy link
Copy Markdown
Contributor
Q A
Fixed Issues? Fixes #18531
Patch: Bug Fix? Yes
Major: Breaking Change?
Minor: New Feature?
Tests Added + Pass? Yes
Documentation PR Link
Any Dependency Changes?
Need backport? 7.x
License MIT

When an array is spread before impure elements (such as [...a, a.push(3)]), passing a directly to .concat(...) evaluates the later arguments before reading a. Clone the spread argument whenever a subsequent element may have side effects (toConsumableArray for constant Array bindings by default, or .slice() under the iterableIsArray assumption).

@babel-bot

Copy link
Copy Markdown
Collaborator

Build successful! You can test your changes in the REPL here: https://babeljs.io/repl/build/63286

@pkg-pr-new

pkg-pr-new Bot commented Nov 13, 2026

Copy link
Copy Markdown

Open in StackBlitz

commit: a553cdd

let lastImpureIndex = -1;

for (const prop of props) {
if (!iterableIsArray) {

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.

The lastImpureIndex is computed only when iterableIsArray is false, so under iterableIsArray assumption, the #18531 is still not fixed.

Given the input [...a, a.push(3)], under this assumption, we can emit

[].concat(a.slice(), [a.push(3)])

so it still outputs [1, 2, 3]. Could you implement it and add a new test case for the iterableIsArray assumption case?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good catch, updated to emit .slice() under iterableIsArray when a later element has side effects and added a test fixture for it.

@JLHwung JLHwung added PR: Bug Fix 🐛 A type of pull request used for our changelog categories 7.x: needs backport labels Nov 13, 2026

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

7.x: needs backport PR: Bug Fix 🐛 A type of pull request used for our changelog categories

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Array spread lowering reads a spread array after later elements have run ([...a, a.push(3)])

3 participants