diff --git a/turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs b/turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs index 8b8ca0c8954..dc523d0988c 100644 --- a/turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs +++ b/turbopack/crates/turbopack-ecmascript/src/analyzer/mod.rs @@ -2449,7 +2449,7 @@ impl JsValue { LogicalOperator::And => all_if_known(list, JsValue::is_truthy), LogicalOperator::Or => any_if_known(list, JsValue::is_truthy), LogicalOperator::NullishCoalescing => { - shortcircuit_if_known(list, JsValue::is_not_nullish, JsValue::is_truthy) + eval_shortcircuit(list, JsValue::is_not_nullish)?.is_truthy() } }, JsValue::Binary(_, box a, op, box b) => { @@ -2460,25 +2460,6 @@ impl JsValue { JsValue::Constant(a), JsValue::Constant(b), ) if a.is_value_type() => Some(a == b), - ( - PositiveBinaryOperator::StrictEqual, - JsValue::Constant(a), - JsValue::Constant(b), - ) if a.is_value_type() => { - let same_type = { - use ConstantValue::*; - matches!( - (a, b), - (Num(_), Num(_)) - | (Str(_), Str(_)) - | (BigInt(_), BigInt(_)) - | (True | False, True | False) - | (Undefined, Undefined) - | (Null, Null) - ) - }; - if same_type { Some(a == b) } else { None } - } ( PositiveBinaryOperator::Equal, JsValue::Constant(ConstantValue::Str(a)), @@ -2527,12 +2508,8 @@ impl JsValue { _ => merge_if_known(values, JsValue::is_nullish), }, JsValue::Logical(_, op, list) => match op { - LogicalOperator::And => { - shortcircuit_if_known(list, JsValue::is_falsy, JsValue::is_nullish) - } - LogicalOperator::Or => { - shortcircuit_if_known(list, JsValue::is_truthy, JsValue::is_nullish) - } + LogicalOperator::And => eval_shortcircuit(list, JsValue::is_falsy)?.is_nullish(), + LogicalOperator::Or => eval_shortcircuit(list, JsValue::is_truthy)?.is_nullish(), LogicalOperator::NullishCoalescing => all_if_known(list, JsValue::is_nullish), }, _ => None, @@ -2560,13 +2537,13 @@ impl JsValue { } => merge_if_known(values, JsValue::is_empty_string), JsValue::Logical(_, op, list) => match op { LogicalOperator::And => { - shortcircuit_if_known(list, JsValue::is_falsy, JsValue::is_empty_string) + eval_shortcircuit(list, JsValue::is_falsy)?.is_empty_string() } LogicalOperator::Or => { - shortcircuit_if_known(list, JsValue::is_truthy, JsValue::is_empty_string) + eval_shortcircuit(list, JsValue::is_truthy)?.is_empty_string() } LogicalOperator::NullishCoalescing => { - shortcircuit_if_known(list, JsValue::is_not_nullish, JsValue::is_empty_string) + eval_shortcircuit(list, JsValue::is_not_nullish)?.is_empty_string() } }, // Booleans are not empty strings @@ -2620,14 +2597,10 @@ impl JsValue { JsValue::Add(_, list) => any_if_known(list, JsValue::is_string), JsValue::Logical(_, op, list) => match op { - LogicalOperator::And => { - shortcircuit_if_known(list, JsValue::is_falsy, JsValue::is_string) - } - LogicalOperator::Or => { - shortcircuit_if_known(list, JsValue::is_truthy, JsValue::is_string) - } + LogicalOperator::And => eval_shortcircuit(list, JsValue::is_falsy)?.is_string(), + LogicalOperator::Or => eval_shortcircuit(list, JsValue::is_truthy)?.is_string(), LogicalOperator::NullishCoalescing => { - shortcircuit_if_known(list, JsValue::is_not_nullish, JsValue::is_string) + eval_shortcircuit(list, JsValue::is_not_nullish)?.is_string() } }, @@ -2790,26 +2763,25 @@ fn any_if_known( all_if_known(list, |x| func(x).map(|x| !x)).map(|x| !x) } -/// Selects the first element of the list where `use_item` is compile-time true. -/// For this element returns the result of `item_value`. Otherwise returns None. -fn shortcircuit_if_known( +/// Selects the first element of the list where `matches` is compile-time true. +/// Returns this element; if no elements match, it returns the last item. +fn eval_shortcircuit( list: impl IntoIterator, - use_item: impl Fn(T) -> Option, - item_value: impl FnOnce(T) -> Option, -) -> Option { + matches: impl Fn(T) -> Option, +) -> Option { let mut it = list.into_iter().peekable(); while let Some(item) = it.next() { if it.peek().is_none() { - return item_value(item); + return Some(item); } else { - match use_item(item) { - Some(true) => return item_value(item), + match matches(item) { + Some(true) => return Some(item), None => return None, _ => {} } } } - None + unreachable!("Binary operators should always have operands.") } // Visiting