diff --git a/crates/oxc_ecmascript/src/constant_evaluation/mod.rs b/crates/oxc_ecmascript/src/constant_evaluation/mod.rs index 9e3fc1ee7850d..28da0650b4b7f 100644 --- a/crates/oxc_ecmascript/src/constant_evaluation/mod.rs +++ b/crates/oxc_ecmascript/src/constant_evaluation/mod.rs @@ -154,7 +154,30 @@ pub trait ConstantEvaluation<'a>: MayHaveSideEffects { Expression::ArrayExpression(arr) => { // If the array is empty, `ToPrimitive` returns `""` if arr.elements.is_empty() { - Some(0.0) + return Some(0.0); + } + if arr.elements.len() == 1 { + let first_element = arr.elements.first().unwrap(); + return match first_element { + ArrayExpressionElement::SpreadElement(_) => None, + // `ToPrimitive` returns `""` for `[,]` + ArrayExpressionElement::Elision(_) => Some(0.0), + match_expression!(ArrayExpressionElement) => { + self.eval_to_number(first_element.to_expression()) + } + }; + } + + let non_spread_element_count = arr + .elements + .iter() + .filter(|e| !matches!(e, ArrayExpressionElement::SpreadElement(_))) + .count(); + // If the array has at least 2 elements, `ToPrimitive` returns a string containing + // `,` which is not included in `StringNumericLiteral` + // So `ToNumber` returns `NaN` + if non_spread_element_count >= 2 { + Some(f64::NAN) } else { None } diff --git a/crates/oxc_minifier/src/peephole/fold_constants.rs b/crates/oxc_minifier/src/peephole/fold_constants.rs index 03007b154b403..0d20783cb8262 100644 --- a/crates/oxc_minifier/src/peephole/fold_constants.rs +++ b/crates/oxc_minifier/src/peephole/fold_constants.rs @@ -1204,6 +1204,16 @@ mod test { fold("a=~0xffffffff", "a=0"); fold("a=~~0xffffffff", "a=-1"); fold("a=~.5", "a=-1"); + + fold("a=+[]", "a=0"); + fold_same("a=+[...foo]"); + fold("a=+[,]", "a=0"); + fold("a=+[0]", "a=0"); + fold("a=+['0x10']", "a=16"); + fold("a=+[[]]", "a=0"); + fold("a=+[0, 1]", "a=NaN"); + test_same("var foo; NOOP(a=+[0, ...foo])"); // can be either `a=0` or `a=NaN` (also `...foo` may have a side effect) + test("var foo; NOOP(a=+[0, ...[foo ? 'foo': ''], 1])", "var foo; NOOP(a=NaN)"); } #[test] diff --git a/crates/oxc_minifier/tests/peephole/esbuild.rs b/crates/oxc_minifier/tests/peephole/esbuild.rs index 5fe4a3c422e5e..a03b6a18d4164 100644 --- a/crates/oxc_minifier/tests/peephole/esbuild.rs +++ b/crates/oxc_minifier/tests/peephole/esbuild.rs @@ -894,7 +894,7 @@ fn constant_evaluation_test() { test("x = +[]", "x = 0;"); test("x = +{}", "x = NaN;"); test("x = +/1/", "x = NaN;"); - test("x = +[1]", "x = +[1];"); + test("x = +[1]", "x = 1;"); test("x = +'123'", "x = 123;"); test("x = +'-123'", "x = -123;"); test("x = +'0x10'", "x = 16;");