swc-project/swc · error

Unknown bit operator {:?}

Error message

Unknown bit operator {:?}

What it means

In the expression simplifier, try_fold_shift constant-folds shift operations once both operands are known pure numbers (lv << rv etc.). The function is only invoked for the `<<`, `>>`, `>>>` operators and the match lists exactly those three; the `_ => unreachable!` arm can only fire if the caller set and the match set desynchronize — an internal invariant, not a user-input condition.

Source

Thrown at crates/swc_ecma_transforms_optimization/src/simplify/expr/mod.rs:1233

        // Bit shift operations
        op!("<<") | op!(">>") | op!(">>>") => {
            fn try_fold_shift(ctx: ExprCtx, op: BinaryOp, left: &Expr, right: &Expr) -> Value<f64> {
                if !left.is_number() || !right.is_number() {
                    return Unknown;
                }

                let (lv, rv) = match (left.as_pure_number(ctx), right.as_pure_number(ctx)) {
                    (Known(lv), Known(rv)) => (lv, rv),
                    _ => unreachable!(),
                };
                let (lv, rv) = (JsNumber::from(lv), JsNumber::from(rv));

                Known(match op {
                    op!("<<") => *(lv << rv),
                    op!(">>") => *(lv >> rv),
                    op!(">>>") => *(lv.unsigned_shr(rv)),

                    _ => unreachable!("Unknown bit operator {:?}", op),
                })
            }
            try_replace!(number, try_fold_shift(expr_ctx, op, left, right))
        }

        // These needs one more check.
        //
        // (a * 1) * 2 --> a * (1 * 2) --> a * 2
        op!("*") | op!("&") | op!("|") | op!("^") => {
            try_replace!(number, perform_arithmetic_op(expr_ctx, op, left, right));

            // Try left.rhs * right
            if let Expr::Bin(BinExpr {
                span: _,
                left: left_lhs,
                op: left_op,
                right: left_rhs,
            }) = &mut **left

View on GitHub (pinned to 5176682b65)

Solutions

  1. Update to a matching swc_core release (simplifier guards and matches ship together).
  2. If you maintain a fork, keep the operator guard that routes to try_fold_shift in sync with its match arms.
  3. Report with a minimal expression if plain parsed input reproduces it.
Defensive patterns

Strategy: validation

Validate before calling

// Only route shift operators if you invoke folding logic yourself
fn is_shift_op(op: BinaryOp) -> bool { matches!(op, op!("<<") | op!(">>") | op!(">>>")) }

Prevention

When it happens

Trigger: Internal simplifier bug where the guard selecting try_fold_shift admits an operator outside {<<, >>, >>>}; or calling the private helper directly with another operator in a fork/patch of swc.

Common situations: Forks of swc modifying the simplifier; swc_core version regressions after operator-set changes; essentially never from ordinary config or source input.

Related errors


AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17). Data as JSON: /api/errors/c2c7874ffd129386. Report an issue: GitHub.