From c0a3ddac28a91a2a6d5aca0b9e4b65180dae6380 Mon Sep 17 00:00:00 2001 From: Boshen <1430279+Boshen@users.noreply.github.com> Date: Thu, 9 Jan 2025 06:49:27 +0000 Subject: [PATCH] fix(minifier): `instanceof` has error throwing side effect (#8378) --- .../src/side_effects/check_for_state_change.rs | 11 ++++++++--- .../src/ast_passes/peephole_remove_dead_code.rs | 1 + crates/oxc_syntax/src/operator.rs | 5 +++++ 3 files changed, 14 insertions(+), 3 deletions(-) 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 07134b57b37f2..5a24c95ef7563 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 @@ -95,10 +95,15 @@ impl<'a> CheckForStateChange<'a, '_> for UnaryExpression<'a> { impl<'a> CheckForStateChange<'a, '_> for BinaryExpression<'a> { fn check_for_state_change(&self, check_for_new_objects: bool) -> bool { + // `instanceof` can throw `TypeError` + if self.operator.is_instance_of() { + return true; + } let left = self.left.check_for_state_change(check_for_new_objects); - let right = self.right.check_for_state_change(check_for_new_objects); - - left || right + if left { + return true; + } + self.right.check_for_state_change(check_for_new_objects) } } diff --git a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs index 98e5d233c5d66..52b15ba339154 100644 --- a/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs +++ b/crates/oxc_minifier/src/ast_passes/peephole_remove_dead_code.rs @@ -717,6 +717,7 @@ mod test { fold("(function k() {}, k(), baz())", "k(), baz()"); fold_same("(0, o.f)();"); fold("var obj = Object((null, 2, 3), 1, 2);", "var obj = Object(3, 1, 2);"); + fold_same("(0 instanceof 0, foo)"); } #[test] diff --git a/crates/oxc_syntax/src/operator.rs b/crates/oxc_syntax/src/operator.rs index 70aa66ef039df..264745ffe1f6d 100644 --- a/crates/oxc_syntax/src/operator.rs +++ b/crates/oxc_syntax/src/operator.rs @@ -268,6 +268,11 @@ impl BinaryOperator { self == Self::In } + /// Returns `true` if this is an [`In`](BinaryOperator::Instanceof) operator. + pub fn is_instance_of(self) -> bool { + self == Self::Instanceof + } + /// Returns `true` for any bitwise operator #[rustfmt::skip] pub fn is_bitwise(self) -> bool {