diff --git a/crates/oxc_ecmascript/src/constant_evaluation/mod.rs b/crates/oxc_ecmascript/src/constant_evaluation/mod.rs index 40212d5bd00cf..e49e8fcbc94fd 100644 --- a/crates/oxc_ecmascript/src/constant_evaluation/mod.rs +++ b/crates/oxc_ecmascript/src/constant_evaluation/mod.rs @@ -430,22 +430,6 @@ pub trait ConstantEvaluation<'a> { left_string.cmp(&right_string) == Ordering::Less, )); } - - // Special case: `typeof a < typeof a` is always false. - if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) = - (left_expr, right_expr) - { - if (left.operator, right.operator) == (UnaryOperator::Typeof, UnaryOperator::Typeof) - { - if let (Expression::Identifier(left), Expression::Identifier(right)) = - (&left.argument, &right.argument) - { - if left.name == right.name { - return Some(ConstantValue::Boolean(false)); - } - } - } - } } // TODO: bigint is handled very differently in the spec diff --git a/crates/oxc_ecmascript/src/side_effects/check_for_state_change.rs b/crates/oxc_ecmascript/src/side_effects/check_for_state_change.rs index f4666b9ae8af9..374aa6300fa6b 100644 --- a/crates/oxc_ecmascript/src/side_effects/check_for_state_change.rs +++ b/crates/oxc_ecmascript/src/side_effects/check_for_state_change.rs @@ -33,11 +33,11 @@ impl<'a, 'b> CheckForStateChange<'a, 'b> for Expression<'a> { .expressions .iter() .any(|expr| expr.check_for_state_change(check_for_new_objects)), - Self::Identifier(_ident) => - /* TODO: ident.reference_flags == ReferenceFlags::Write */ - { - false - } + Self::Identifier(ident) => match ident.name.as_str() { + "undefined" | "NaN" | "Infinity" => false, + // Reference read can have a side effect. + _ => true, + }, Self::UnaryExpression(unary_expr) => { unary_expr.check_for_state_change(check_for_new_objects) } diff --git a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs index 85574fe28081d..9ea3a54147e59 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_fold_constants.rs @@ -6,7 +6,7 @@ use oxc_ecmascript::{ use oxc_span::{GetSpan, SPAN}; use oxc_syntax::{ number::{NumberBase, ToJsString}, - operator::{BinaryOperator, LogicalOperator, UnaryOperator}, + operator::{BinaryOperator, LogicalOperator}, }; use oxc_traverse::{Ancestor, Traverse, TraverseCtx}; @@ -411,23 +411,6 @@ impl<'a, 'b> PeepholeFoldConstants { return Tri::from(left_string == right_string); } - if let (Expression::UnaryExpression(left), Expression::UnaryExpression(right)) = - (left_expr, right_expr) - { - if (left.operator, right.operator) - == (UnaryOperator::Typeof, UnaryOperator::Typeof) - { - if let (Expression::Identifier(left), Expression::Identifier(right)) = - (&left.argument, &right.argument) - { - if left.name == right.name { - // Special case, typeof a == typeof a is always true. - return Tri::True; - } - } - } - } - Tri::Unknown } ValueType::Undefined | ValueType::Null => Tri::True, @@ -713,28 +696,28 @@ mod test { fn test_boolean_number_comparison() { test_same("!x==+y"); test_same("!x<=+y"); - test("!x !== +y", "true"); + test_same("!x !== +y"); } #[test] fn test_number_boolean_comparison() { test_same("+x==!y"); test_same("+x<=!y"); - test("+x === !y", "false"); + test_same("+x === !y"); } #[test] fn test_boolean_string_comparison() { test_same("!x==''+y"); test_same("!x<=''+y"); - test("!x !== '' + y", "true"); + test_same("!x !== '' + y"); } #[test] fn test_string_boolean_comparison() { test_same("''+x==!y"); test_same("''+x<=!y"); - test("'' + x === !y", "false"); + test_same("'' + x === !y"); } #[test] @@ -746,8 +729,8 @@ mod test { test("+'a' < +'b'", "false"); test_same("typeof a < 'a'"); test_same("'a' >= typeof a"); - test("typeof a < typeof a", "false"); - test("typeof a >= typeof a", "true"); + test_same("typeof a < typeof a"); + test_same("typeof a >= typeof a"); test("typeof 3 > typeof 4", "false"); test("typeof function() {} < typeof function() {}", "false"); test("'a' == 'a'", "true"); @@ -756,11 +739,11 @@ mod test { test_same("typeof a != 'number'"); test_same("'undefined' == typeof a"); test_same("'undefined' == typeof a"); - test("typeof a == typeof a", "true"); + test_same("typeof a == typeof a"); test("'a' === 'a'", "true"); test("'b' !== 'a'", "true"); - test("typeof a === typeof a", "true"); - test("typeof a !== typeof a", "false"); + test_same("typeof a === typeof a"); + test_same("typeof a !== typeof a"); test_same("'' + x <= '' + y"); test_same("'' + x != '' + y"); test_same("'' + x === '' + y"); @@ -783,7 +766,7 @@ mod test { test("1 !== '1'", "true"); test_same("+x>''+y"); test_same("+x==''+y"); - test("+x !== '' + y", "true"); + test_same("+x !== '' + y"); } #[test] @@ -799,7 +782,7 @@ mod test { test("'1' !== 1", "true"); test_same("''+x<+y"); test_same("''+x==+y"); - test("'' + x === +y", "false"); + test_same("'' + x === +y"); } #[test] @@ -901,8 +884,8 @@ mod test { test_same("x>=NaN"); test_same("NaN==x"); test_same("x!=NaN"); - test("NaN === x", "false"); - test("x !== NaN", "true"); + test_same("NaN === x"); + test_same("x !== NaN"); test_same("NaN==foo()"); } @@ -1109,7 +1092,7 @@ mod test { fn test_fold_void() { test_same("void 0"); test("void 1", "void 0"); - test("void x", "void 0"); + test_same("void x"); test_same("void x()"); } diff --git a/tasks/coverage/snapshots/runtime.snap b/tasks/coverage/snapshots/runtime.snap index d37836e39677d..ba4952ecf2e73 100644 --- a/tasks/coverage/snapshots/runtime.snap +++ b/tasks/coverage/snapshots/runtime.snap @@ -2,7 +2,7 @@ commit: 06454619 runtime Summary: AST Parsed : 18444/18444 (100.00%) -Positive Passed: 18269/18444 (99.05%) +Positive Passed: 18273/18444 (99.07%) tasks/coverage/test262/test/annexB/language/function-code/if-decl-else-decl-a-func-existing-block-fn-no-init.js minify error: Test262Error: Expected SameValue(«function f(){}», «undefined») to be true @@ -420,15 +420,6 @@ minify error: Test262Error: #3.2: -0 - 0 === - 0. Actual: +0 tasks/coverage/test262/test/language/expressions/super/call-spread-obj-getter-init.js transform error: Test262Error: Expected SameValue(«true», «false») to be true -tasks/coverage/test262/test/language/expressions/template-literal/literal-expr-tostr-error.js -minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all - -tasks/coverage/test262/test/language/expressions/template-literal/middle-list-many-expr-tostr-error.js -minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all - -tasks/coverage/test262/test/language/expressions/template-literal/middle-list-one-expr-tostr-error.js -minify error: Test262Error: Expected a Test262Error to be thrown but no exception was thrown at all - tasks/coverage/test262/test/language/expressions/unary-plus/S11.4.6_A3_T3.js minify error: Test262Error: #4: +"INFINITY" === Not-a-Number. Actual: Infinity @@ -438,9 +429,6 @@ minify error: Test262Error: #3.2: +(-0) === -0. Actual: +0 tasks/coverage/test262/test/language/expressions/unary-plus/bigint-throws.js minify error: Test262Error: +0n throws TypeError Expected a TypeError to be thrown but no exception was thrown at all -tasks/coverage/test262/test/language/expressions/void/S11.4.2_A2_T2.js -minify error: Test262Error: Expected a ReferenceError to be thrown but no exception was thrown at all - tasks/coverage/test262/test/language/global-code/decl-func.js codegen error: Test262Error: descriptor should not be configurable