Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 9 additions & 1 deletion src/ast/known_global.rs
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,15 @@ impl KnownGlobal {
// > 1
_ => {
// new Array(1, 2, 3) -> [1, 2, 3]
// But NOT new Array(3) which creates an array with 3 empty slots
// 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.
Comment on lines +246 to +247

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.

If you need a paragraph-long comment to justify why the workaround is OK, the code is wrong — fix the code

if e.args
.slice()
.iter()
.any(|arg| matches!(arg.data, js_ast::ExprData::ESpread(_)))
{
return Some(Self::call_from_new(e, loc));
}
Some(js_ast::Expr::init(
E::Array {
items: bun_alloc::AstAlloc::take(&mut e.args),
Expand Down
3 changes: 2 additions & 1 deletion src/jsc/RuntimeTranspilerCache.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,8 @@ bun_core::declare_scope!(cache, visible);
/// u8/u16/u32 ids and implied slots dropped, instead of fixed u32 arrays.
/// Version 27: ModuleInfo string table holds Latin-1 / UTF-16 bodies, not WTF-8.
/// Version 28: the define table and `--drop` entries participate in the features hash.
const EXPECTED_VERSION: u32 = 28;
/// Version 29: `new Array(x, ...spread)` is no longer folded into an array literal.
const EXPECTED_VERSION: u32 = 29;

/// Source files smaller than this are not written to / read from the on-disk
/// transpiler cache. Originally 50 KiB, which excluded almost every file in a
Expand Down
14 changes: 13 additions & 1 deletion test/bundler/bundler_minify.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1197,6 +1197,8 @@ describe("bundler", () => {
capture(new Array());
capture(new Array(3));
capture(new Array(1, 2, 3));
capture(new Array(...unknownValue));
capture(new Array(5, ...unknownValue));

// Test Array with non-numeric single arguments (should convert to literal)
capture(new Array("string"));
Expand Down Expand Up @@ -1237,6 +1239,8 @@ describe("bundler", () => {
2,
3
]`, // new Array(1, 2, 3) -> [1, 2, 3]
"Array(...unknownValue)", // a spread may leave a single number behind, which is a length
"Array(5, ...unknownValue)",
`[
"string"
]`, // new Array("string") -> ["string"]
Expand Down Expand Up @@ -1329,6 +1333,12 @@ describe("bundler", () => {
const a3 = new Array(n);
const a4 = Array(n);
capture(a3.length === a4.length && a3.length === 3 && a3[0] === undefined);

// A spread can leave a single number behind at runtime, and then it is a length
const none = [];
const a5 = new Array(5, ...none);
capture(a5.length === 5);
capture(0 in a5 === false);

// Test Object semantics
const o1 = new Object();
Expand Down Expand Up @@ -1357,6 +1367,8 @@ describe("bundler", () => {
"0 in sparse === !1",
'JSON.stringify(sparse) === "[null,null,null,null,null]"',
"a3.length === a4.length && a3.length === 3 && a3[0] === void 0",
"a5.length === 5",
"0 in a5 === !1",
"typeof o1 === typeof o2",
"o1.constructor === o2.constructor",
"typeof f1 === typeof f2",
Expand All @@ -1367,7 +1379,7 @@ describe("bundler", () => {
minifySyntax: true,
target: "bun",
run: {
stdout: "true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue",
stdout: "true\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue\ntrue",
},
});

Expand Down
Loading