swc-project/swc · error
spread should be removed before applying generator
Error message
spread should be removed before applying generator
What it means
When the es2015 generator pass converts an object literal inside a generator body into a sequence of assignments to a temp object, it asserts that no spread properties remain (PropOrSpread::Spread). Object spread (`{...x}`) is an ES2018 feature that the es2018::object_rest_spread pass is expected to remove (rewriting to Object.assign/_extends) before generator lowering runs.
Source
Thrown at crates/swc_ecma_compat_es2015/src/generator.rs:740
.props
.iter_mut()
.take(num_initial_properties)
.map(|v| v.take())
.collect(),
}
.into(),
None,
);
let mut expressions = node
.props
.iter_mut()
.skip(num_initial_properties)
.map(|v| v.take())
.fold(Vec::<CompiledProp>::new(), |mut props, p| {
match p {
PropOrSpread::Spread(_) => {
unreachable!("spread should be removed before applying generator")
}
PropOrSpread::Prop(p) => match *p {
Prop::Getter(p) => {
if let Some(CompiledProp::Accessor(g, _)) =
props.iter_mut().find(|prev| match prev {
CompiledProp::Accessor(_, Some(s)) => {
s.key.eq_ignore_span(&p.key)
}
_ => false,
})
{
*g = Some(p);
} else {
props.push(CompiledProp::Accessor(Some(p), None))
}
}
Prop::Setter(p) => {
if let Some(CompiledProp::Accessor(_, s)) =View on GitHub (pinned to 5176682b65)
Solutions
- Insert es2018::object_rest_spread (and the rest of the es2018 block) before es2015::generator in manual chains.
- Use preset_env / CompatEnv so ordering is handled for you.
- Verify all swc crates resolve to one swc_core version.
- If ordering is right, report with a repro of `{...spread}` inside a generator.
Example fix
// before: object spread reaches the generator pass
let pass = Chain::new(swc_ecma_compat_es2015::generator());
// after
let pass = Chain::new(
swc_ecma_compat_es2018::object_rest_spread(Default::default()),
swc_ecma_compat_es2015::generator(),
); Defensive patterns
Strategy: validation
Validate before calling
// Reject object-spread before the generator pass runs
use swc_ecma_ast::*; use swc_ecma_visit::{Visit, VisitWith};
struct SpreadScan(bool); impl Visit for SpreadScan {
fn visit_prop_or_spread(&mut self, p: &PropOrSpread) {
self.0 |= matches!(p, PropOrSpread::Spread(_));
p.visit_children_with(self);
}
}
// if SpreadScan scan is true, run es2018 object_rest_spread before generator() Prevention
- Order es2018 object_rest_spread before es2015 generator in every chain targeting ES5.
- Smoke-test generators containing `{...obj}` literals through your pipeline.
- Rely on preset_env ordering rather than manual pass lists.
When it happens
Trigger: Running swc_ecma_compat_es2015 generator (or a chain containing it) on code with object-spread properties inside generator functions / async functions, when es2018::object_rest_spread has not executed first — typically a manually ordered pass chain or preset ordering broken by version skew.
Common situations: Custom Chain-of-passes drivers targeting ES5 that run the generator pass without the es2018 spread lowering; spack/bundlers embedding swc_core with partial compat pipelines; swc_core downgrades.
Related errors
- using declaration must be removed by previous pass
- object rest pattern should be removed by es2018::object_rest
- using declaration must be removed by previous pass
- unknown compound assignment operator
- assignment property be removed before generator pass
AI-assisted analysis of swc-project/swc@5176682b65 (2026-08-17).
Data as JSON: /api/errors/88a3f23a38e974c0.
Report an issue: GitHub.