swc-project/swc · error
Object rest pattern should be removed by es2018::object_rest
Error message
Object rest pattern should be removed by es2018::object_rest_spread pass
What it means
The es2015 destructuring pass lowers object patterns property by property; object rest (`const { a, ...rest } = obj`) belongs to es2018::object_rest_spread, which must run earlier and eliminate ObjectPatProp::Rest. If a rest element is still present when destructuring runs, it panics because it cannot express 'all remaining properties'.
Source
Thrown at crates/swc_ecma_compat_es2015/src/destructuring.rs:420
}
None => {
let var_decl = VarDeclarator {
span: prop_span,
name: key.clone().into(),
init: Some(Box::new(make_ref_prop_expr(
&ref_ident,
key.clone().into(),
computed,
))),
definite: false,
};
let mut var_decls = vec![var_decl];
var_decls.visit_mut_with(self);
decls.extend(var_decls);
}
}
}
ObjectPatProp::Rest(..) => unreachable!(
"Object rest pattern should be removed by es2018::object_rest_spread \
pass"
),
#[cfg(swc_ast_unknown)]
_ => panic!("unable to access unknown nodes"),
}
}
}
Pat::Assign(AssignPat {
span,
left,
right: def_value,
..
}) => {
let init = if let Some(init) = decl.init {
let tmp_ident = match &*init {
Expr::Ident(ref i) if i.ctxt != SyntaxContext::empty() => i.clone(),
View on GitHub (pinned to 5176682b65)
Solutions
- Use the standard compat chain (swc core build/targets) which orders object_rest_spread before destructuring
- In a custom chain, prepend swc_ecma_compat_es2018::object_rest_spread() before es2015 destructuring
- Avoid object rest syntax in inputs when you must run destructuring alone
Example fix
// before (custom chain, wrong order) let passes = vec![destructuring()]; // after let passes = vec![ Box::new(swc_ecma_compat_es2018::object_rest_spread()), destructuring(), ];
Defensive patterns
Strategy: validation
Validate before calling
// Detect object rest patterns before running destructuring standalone
let object_rest = regex::Regex::new(r"\{\s*[^}]*\.\.\.[A-Za-z_$][\w$]*\s*\}").unwrap();
if object_rest.is_match(&source) {
return Err("object rest requires es2018::object_rest_spread before destructuring".into());
} Type guard
// Guard AST before destructuring: no ObjectPatProp::Rest may remain
fn object_rest_removed(m: &swc_ecma_ast::Module) -> bool {
struct V(bool);
impl Visit for V {
fn visit_object_pat_prop(&mut self, p: &ObjectPatProp) {
if matches!(p, ObjectPatProp::Rest(_)) { self.0 = false; }
p.visit_children_with(self);
}
}
let mut v = V(true);
m.visit_with(&mut v);
v.0
} Try / catch
if let Err(p) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| destructuring(&mut program))) {
if panic_message(&p).contains("object_rest_spread") {
// prepend swc_ecma_compat_es2018::object_rest_spread() and retry
} else { std::panic::resume_unwind(p); }
} Prevention
- Use swc's preset chain so object_rest_spread always precedes destructuring
- In custom chains, order passes newest-syntax-first (es2018+ before es2015)
- Add pipeline smoke tests covering object rest, spread, and class properties
When it happens
Trigger: Running swc_ecma_compat_es2015::destructuring standalone — without es2018::object_rest_spread ahead of it — on code using object rest patterns in declarations, assignments, or function parameters.
Common situations: Hand-assembled transform chains instead of the preset; migrating old pipelines after object rest syntax was added; tools applying only a subset of es2015 passes to reduce build time.
Related errors
- using declaration must be removed by previous pass
- TsParameterProperty should be removed by typescript::strip p
- assign property in object literal is invalid
- rest pattern should handled by array pattern handler: {:?}
- internal error: entered unreachable code
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/e560a78dee020c5e.
Report an issue: GitHub.