swc-project/swc · error

illegal conversion: Cannot convert {:?} to Pattern

Error message

illegal conversion: Cannot convert {:?} to Pattern

What it means

The `From<PatOutput> for Pattern` impl converts babelify's intermediate pattern into an estree `Pattern`, which models only destructuring forms: Assignment, Array, Object. Every other PatOutput variant — Id, Rest, and Expr included — falls into `_` and panics. It is a type-shape mismatch: the value is a legitimate SWC pattern but Babel's Pattern type cannot represent it.

Source

Thrown at crates/swc_estree_compat/src/babelify/pat.rs:52

            Pat::Assign(a) => PatOutput::Assign(a.babelify(ctx)),
            Pat::Expr(e) => PatOutput::Expr(Box::alloc().init(e.babelify(ctx).into())),
            Pat::Invalid(_) => panic!(
                "illegal conversion: Cannot convert {:?} to PatOutput",
                &self
            ),
            #[cfg(swc_ast_unknown)]
            _ => panic!("unable to access unknown nodes"),
        }
    }
}

impl From<PatOutput> for Pattern {
    fn from(pat: PatOutput) -> Self {
        match pat {
            PatOutput::Assign(a) => Pattern::Assignment(a),
            PatOutput::Array(a) => Pattern::Array(a),
            PatOutput::Object(o) => Pattern::Object(o),
            _ => panic!("illegal conversion: Cannot convert {:?} to Pattern", &pat),
        }
    }
}

impl From<PatOutput> for ObjectPropVal {
    fn from(pat: PatOutput) -> Self {
        match pat {
            PatOutput::Expr(e) => ObjectPropVal::Expr(e),
            PatOutput::Id(p) => ObjectPropVal::Pattern(PatternLike::Id(p)),
            PatOutput::Array(p) => ObjectPropVal::Pattern(PatternLike::ArrayPat(p)),
            PatOutput::Rest(p) => ObjectPropVal::Pattern(PatternLike::RestEl(p)),
            PatOutput::Object(p) => ObjectPropVal::Pattern(PatternLike::ObjectPat(p)),
            PatOutput::Assign(p) => ObjectPropVal::Pattern(PatternLike::AssignmentPat(p)),
        }
    }
}

impl From<PatOutput> for LVal {

View on GitHub (pinned to 5176682b65)

Solutions

  1. Route only Array/Object/Assignment patterns into Pattern-typed slots; keep identifiers in Id-typed slots (PatternLike/Param/LVal)
  2. Validate patterns before conversion and reject non-destructuring ones with a diagnostic
  3. Fix the transform or input that produced the misplaced pattern
  4. Maintainer: change call sites to use PatternLike/Param targets instead of Pattern where Ids are legal

Example fix

// before
let pat: Pattern = pat_output.into(); // panics for Id/Rest/Expr

// after
let pat: Pattern = match pat_output {
    PatOutput::Array(a) => Pattern::Array(a),
    PatOutput::Object(o) => Pattern::Object(o),
    PatOutput::Assign(a) => Pattern::Assignment(a),
    other => return Err(anyhow!("not a destructuring pattern: {other:?}")),
};
Defensive patterns

Strategy: validation

Validate before calling

use swc_ecma_ast::Pat;

fn is_destructuring_only(p: &Pat) -> bool {
    matches!(p, Pat::Array(_) | Pat::Object(_) | Pat::Assign(_))
}

Type guard

fn fits_estree_pattern(p: &Pat) -> bool {
    matches!(p, Pat::Array(_) | Pat::Object(_) | Pat::Assign(_))
}

Try / catch

use std::panic::{catch_unwind, AssertUnwindSafe};

catch_unwind(AssertUnwindSafe(|| pat_output.into_pattern()))
    .map_err(|p| anyhow!("cannot convert pattern to estree Pattern: {:?}", p))?;

Prevention

When it happens

Trigger: Call `.into()` / `Pattern::from` on a PatOutput that is an identifier, a rest element (`...r`), or a wrapped expression, in any slot typed `swc_estree_ast::Pattern` — usually a recovered parse or a transform that placed a non-destructuring pattern into a pattern-only position.

Common situations: Codemods/transforms rewriting parameters or defaults and leaving Ident/Rest where a destructuring pattern is required; babelifying error-recovered ASTs; direct users of the crate's public From<PatOutput> impls.

Related errors


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