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 (swc_ecma_compat_es2015::destructure) rewrites object binding patterns into a sequence of assignments. While expanding the properties of an object pattern it explicitly asserts that ObjectPatProp::Rest never appears, because rest elements (e.g. `const {a, ...rest} = obj`) are supposed to be lowered earlier by the es2018::object_rest_spread pass. Hitting this unreachable! means the compat pass chain ran in the wrong order or was hand-assembled without the es2018 pass.
Source
Thrown at crates/swc_ecma_compat_es2015/src/destructuring.rs:1028
}
None => {
exprs.push(
AssignExpr {
span,
left: key.clone().into(),
op: op!("="),
right: Box::new(make_ref_prop_expr(
&ref_ident,
key.clone().into(),
computed,
)),
}
.into(),
);
}
}
}
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"),
}
}
// Last one should be object itself.
exprs.push(ref_ident.into());
*expr = SeqExpr {
span: DUMMY_SP,
exprs,
}
.into();
}
View on GitHub (pinned to 5176682b65)
Solutions
- If you build a manual pass chain, insert swc_ecma_compat_es2018::object_rest_spread(Default::default()) BEFORE swc_ecma_compat_es2015::destructure (and before es2015::generator).
- Prefer the standard pipelines (swc_ecma_preset_env / CompatEnv / full `es` compat chain) which order passes correctly, instead of hand-picking passes.
- Align all swc crates on one swc_core version so pass wiring is consistent.
- If ordering is already correct in your version, file an swc issue with a minimal repro of the rest-element input.
Example fix
// before: rest element panics because es2018 pass never ran
let pass = Chain::new(swc_ecma_compat_es2015::destructure());
// after: lower object rest/spread first, then destructure
let pass = Chain::new(
swc_ecma_compat_es2018::object_rest_spread(Default::default()),
swc_ecma_compat_es2015::destructure(),
); Defensive patterns
Strategy: validation
Validate before calling
// Before applying es2015::destructure, assert no object-rest remains
use swc_ecma_ast::*; use swc_ecma_visit::{Visit, VisitWith};
struct RestChecker; impl Visit for RestChecker {
fn visit_object_pat_prop(&mut self, p: &ObjectPatProp) {
if let ObjectPatProp::Rest(_) = p { panic!("run object_rest_spread before destructure"); }
p.visit_children_with(self);
}
}
// program.visit_with(&mut RestChecker); Try / catch
// Rust panics cross FFI/thread boundaries; contain them at your driver edge
let result = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| {
program.apply_mut(chain)
}));
if result.is_err() { /* extract payload, surface 'pass ordering' error to user */ } Prevention
- Prefer preset_env/CompatEnv over hand-assembled compat chains.
- Never place es2015 passes before es2018 object_rest_spread in a chain.
- Keep every swc crate on the same swc_core release (cargo tree -i swc_core).
When it happens
Trigger: Compiling source containing an object destructuring rest element while invoking swc_ecma_compat_es2015::destructure directly (or in a custom swc_core Pass chain) without running swc_ecma_compat_es2018::object_rest_spread first. Also triggered by swc_core version skew where the preset-env/compat pass ordering changed.
Common situations: Codemod or bundler authors building custom `Chain`s of compat passes instead of using preset_env/CompatEnv; projects mixing swc_core versions across crates (e.g. swc_ecma_compat_es2015 from a different version than the driver); downgrading swc after a pass-list refactor.
Related errors
- using declaration must be removed by previous pass
- spread should be removed before applying generator
- using declaration must be removed by previous pass
- illegal conversion: Cannot convert {:?} to PatOutput
- illegal conversion: Cannot convert {:?} to Pattern
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/4c5f5f3b6b0343e0.
Report an issue: GitHub.