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

  1. Use the standard compat chain (swc core build/targets) which orders object_rest_spread before destructuring
  2. In a custom chain, prepend swc_ecma_compat_es2018::object_rest_spread() before es2015 destructuring
  3. 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

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


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