swc-project/swc · error
Pattern {:?}
Error message
Pattern {:?} What it means
The ES2015 destructuring transform lowers destructuring declarations for Ident, Array, Object and Assign patterns. Any other `Pat` variant used as the name of a `VarDeclarator` — in practice `Pat::Invalid` produced by error-recovery parsing, or programmatically built AST — falls into `_ => unimplemented!("Pattern {:?}", decl)`.
Source
Thrown at crates/swc_ecma_compat_es2015/src/destructuring.rs:470
// tmp === void 0 ? def_value : tmp
Some(Box::new(make_cond_expr(tmp_ident, def_value)))
} else {
Some(def_value)
};
let var_decl = VarDeclarator {
span,
name: *left,
init,
definite: false,
};
let mut var_decls = vec![var_decl];
var_decls.visit_mut_with(self);
decls.extend(var_decls);
}
_ => unimplemented!("Pattern {:?}", decl),
}
}
}
#[fast_path(DestructuringVisitor)]
impl VisitMut for Destructuring {
noop_visit_mut_type!(fail);
impl_for_for_stmt!(visit_mut_for_in_stmt, ForInStmt);
impl_for_for_stmt!(visit_mut_for_of_stmt, ForOfStmt);
impl_visit_mut_fn!();
fn visit_mut_module_items(&mut self, n: &mut Vec<ModuleItem>) {
self.visit_mut_stmt_like(n);
}
View on GitHub (pinned to d7d7434666)
Solutions
- Treat parser errors as fatal — do not run compat transforms on an AST recovered from a failed parse
- Validate that every VarDeclarator name is Ident/Array/Object/Assign before running the pass
- Reduce to a minimal input and report the offending pattern kind upstream
Example fix
// before: transforming an error-recovered AST let module = parser.parse_module().ok().unwrap_or_else(|| build_partial_module()); module.visit_mut_with(&mut destructuring(c)); // after: abort on parse errors let module = parser.parse_module()?; module.visit_mut_with(&mut destructuring(c));
Defensive patterns
Strategy: validation
Validate before calling
// Rust: validate declarator patterns before the destructuring pass
fn patterns_are_supported(m: &Module) -> bool {
fn ok(p: &Pat) -> bool { matches!(p, Pat::Ident(..) | Pat::Array(..) | Pat::Object(..) | Pat::Assign(..)) }
m.body.iter().all(|i| match i {
ModuleItem::Stmt(Stmt::Decl(Decl::Var(v))) => v.decls.iter().all(|d| ok(&d.name)),
_ => true,
})
} Type guard
fn is_valid_destructuring_pat(p: &Pat) -> bool {
matches!(p, Pat::Ident(..) | Pat::Array(..) | Pat::Object(..) | Pat::Assign(..))
} Prevention
- Abort on parse errors instead of transforming recovered ASTs
- When building AST programmatically, assert every declarator name is one of the four supported patterns
When it happens
Trigger: Feed the destructuring pass a `VarDeclarator` whose name is `Pat::Invalid` or `Pat::Rest`: typically a module parsed in error-recovery mode (errors collected but an AST still returned) or an AST constructed/mutated by a plugin.
Common situations: Custom tooling and plugins that build or mutate AST without validating patterns; pipelines that ignore parser errors and keep transforming; inputs from codegen that emit invalid patterns.
Related errors
AI-assisted analysis of swc-project/swc@d7d7434666 (2026-08-16).
Data as JSON: /api/errors/d69041f64c278f0a.
Report an issue: GitHub.