Repository navigation
minify: do not fold new Array(x, ...spread) into an array literal - #41828
Conversation
With more than one argument, minify_syntax folds new Array(a, b) into [a, b]. When an argument is a spread, the argument count is not known until runtime: new Array(5, ...rest) is new Array(5), a length, when rest is empty, but the fold produced [5]. Keep the constructor call for any spread argument, as the single-argument case already does.
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: ASSERTIVE Plan: Essentials Run ID: 📒 Files selected for processing (3)
Included review availability: Your plan provides up to 10 included reviews per hour; 7 remain after this review. WalkthroughChangesThe minifier now preserves Array constructor minification
Suggested reviewers: Merge Risk: ⚪ Minimal · up to Minified spread-based Array construction now preserves sparse-array semantics, with cache invalidation and regression coverage included. No current merge-blocking risk remains. 🚥 Pre-merge checks | ✅ 4✅ Passed checks (4 passed)
Comment |
|
Status: ready for review. Reproduced on Bun 1.4.3 with: // entry.js
const none = [];
const a5 = new Array(5, ...none);
console.log(a5.length, 0 in a5);
With this branch both print |
| // But NOT new Array(3) which creates an array with 3 empty slots, | ||
| // and `new Array(5, ...rest)` is `new Array(5)` when `rest` is empty. |
There was a problem hiding this comment.
If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code
|
Updated 11:40 PM PT - Sep 6th, 2026
⏳ @autofix-ci[bot], your commit fb5b797 is still building in |
…al (absorb bun 8940b0eec7) minify_global_constructor's >1-argument branch folded arguments into a literal without checking for spread: new Array(5, ...rest) became [5, ...rest], wrong when rest is empty (5 holes vs [5]). Any spread argument now keeps the call_from_new form. RUNTIME_TRANSPILER_CACHE_VERSION 20->21 (minify_syntax output shape change; mirrors upstream expected_version 28->29). Upstream: oven-sh/bun#41828. Co-Authored-By: Claude <noreply@anthropic.com>
Problem
minify_syntax,new Array(5, ...rest)becomes[5, ...rest]. Whenrestis empty the original meansnew Array(5), five holes, and the fold is[5]. Forconst none = []; const a = new Array(5, ...none); console.log(a.length, 0 in a)Node prints5 false. Bun 1.4.3 prints1 trueunderbun runand inbun build --minify-syntaxoutput.KnownGlobal::minify_global_constructor(src/ast/known_global.rs:244). It folds the arguments into a literal without checking for a spread, so the argument count can differ at runtime.Fix
Array(5, ...rest)instead of a literal. This is thecall_from_newform the single-argument branch already uses when the argument may be a number.Arraycalled as a function behaves likenew Array(ECMA-262 23.1.1). Only the literal fold was unsound.EXPECTED_VERSIONinRuntimeTranspilerCache.rsmoves to 29: the runtime transpiler enablesminify_syntax, so its cached output changes.test/bundler/bundler_minify.test.ts(one case captures the output, one runs it, both fail on 1.4.3). Alsobundler_npm.test.tsandminify-new-array-with-if.test.ts.Background
minify_global_constructoris the byte-saving rewrite from feat(minify): optimize Error constructors by removing 'new' keyword #22493:new Object()to{},new Array(1, 2)to[1, 2], andnewdropped from constructors that behave the same when called.new Array(n)with one number makes a sparse array of lengthn. Any other argument list makes an array of the arguments. A spread hides which case applies until runtime.new Error()(and other known-global constructs) into calls that JSC tail-calls #37388, closed in favour of Keep stack frames and positions when the runtime transpiler minifies syntax #41580. It is independent of the stack-frame change there.Notes
new Array(...xs)alone was already safe: it is the single-argument branch and stays a call.minify_global_constructoronbundle, which hides this underbun runbut not inbun build --minifyoutput. This PR fixes the fold itself, so it is needed either way.