swc-project/swc · error

add_effects for class expression

Error message

add_effects for class expression

What it means

`ExprCtx::extract_side_effects_to` in swc_ecma_utils walks an expression to keep only its side-effectful parts; it handles calls, member accesses, unary/seq/assign, tagged templates, etc., but class expressions panic because their side effects (extends clause, computed keys, decorators) are not modeled. The optimizer's expr simplifier and the minifier call it when collapsing member accesses on array literals into sequence expressions.

Source

Thrown at crates/swc_ecma_utils/src/lib.rs:2021

                    self.extract_side_effects_to(v, *e.expr);

                    v
                });
            }

            Expr::TaggedTpl(TaggedTpl { tag, tpl, .. }) => {
                self.extract_side_effects_to(to, *tag);

                tpl.exprs
                    .into_iter()
                    .for_each(|e| self.extract_side_effects_to(to, *e));
            }
            Expr::Tpl(Tpl { exprs, .. }) => {
                exprs
                    .into_iter()
                    .for_each(|e| self.extract_side_effects_to(to, *e));
            }
            Expr::Class(ClassExpr { .. }) => unimplemented!("add_effects for class expression"),

            Expr::JSXMember(..)
            | Expr::JSXNamespacedName(..)
            | Expr::JSXEmpty(..)
            | Expr::JSXElement(..)
            | Expr::JSXFragment(..) => to.push(Box::new(expr)),

            Expr::TsTypeAssertion(TsTypeAssertion { expr, .. })
            | Expr::TsNonNull(TsNonNullExpr { expr, .. })
            | Expr::TsAs(TsAsExpr { expr, .. })
            | Expr::TsConstAssertion(TsConstAssertion { expr, .. })
            | Expr::TsInstantiation(TsInstantiation { expr, .. })
            | Expr::TsSatisfies(TsSatisfiesExpr { expr, .. }) => {
                self.extract_side_effects_to(to, *expr)
            }
            Expr::OptChain(..) => to.push(Box::new(expr)),

            Expr::Invalid(..) => unreachable!(),

View on GitHub (pinned to d7d7434666)

Solutions

  1. Disable the triggering optimization: turn off jsc.minify (or the specific simplify/compress pass) for files that hit this
  2. Refactor class expressions inside array literals into const declarations before the array
  3. Reduce to a minimal repro and report upstream — the `Expr::Class` arm of extract_side_effects_to needs an implementation

Example fix

// before
const x = [class {}, 1][1];

// after
const _c = class {};
const x = [_c, 1][1];
Defensive patterns

Strategy: try-catch

Type guard

// Rust: detect class expressions inside array literals that may be simplified
fn array_literal_contains_class(e: &Expr) -> bool {
    matches!(e, Expr::Array(ArrayLit { elems, .. })
        if elems.iter().flatten().any(|el| matches!(&*el.expr, Expr::Class(..))))
}

Try / catch

// Rust: isolate minification of untrusted bundles
let out = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
    minify(source, &options)
}));
match out {
    Ok(r) => r,
    Err(_) => { /* log the panic and fall back to minify with compress disabled for this file */ }
}

Prevention

When it happens

Trigger: Run the optimizer's simplify pass or jsc.minify compress over code where an array literal containing a class expression is reordered — e.g. `[class {}, x, y][1]` — so preceding elements must be reduced to side effects.

Common situations: Minifying third-party bundles; codebases that register class expressions in arrays (DI containers, metadata registries); enabling member-expression simplification on literals under jsc.minify.compress or the optimizer.

Related errors


AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16). Data as JSON: /api/errors/6697c936ed19b24c. Report an issue: GitHub.