swc-project/swc · error
using declaration must be removed by previous pass
Error message
using declaration must be removed by previous pass
What it means
The es2015 generator pass also rewrites for-of loops that appear inside converted functions: it extracts the loop head to emit the assignment `head = _key`. It handles VarDecl and Pat heads but panics on ForHead::UsingDecl because using-declarations (`for (using x of xs)`) must be lowered by swc_ecma_transforms_proposal::explicit_resource_management before generator conversion.
Source
Thrown at crates/swc_ecma_compat_es2015/src/generator.rs:1918
// Assign to user's variable
let variable = match node.left {
ForHead::VarDecl(initializer) => {
for variable in initializer.decls.iter() {
self.hoist_variable_declaration(&Ident::from(
variable.name.as_ident().unwrap(),
));
}
initializer.decls[0].name.clone()
}
ForHead::Pat(mut initializer) => {
initializer.visit_mut_with(self);
*initializer
}
ForHead::UsingDecl(..) => {
unreachable!("using declaration must be removed by previous pass")
}
#[cfg(swc_ast_unknown)]
_ => panic!("unable to access unknown nodes"),
};
self.emit_assignment(variable.try_into().unwrap(), Box::new(key.into()), None);
self.transform_and_emit_embedded_stmt(*node.body);
self.mark_label(increment_label);
self.emit_stmt(
ExprStmt {
span: DUMMY_SP,
expr: UpdateExpr {
span: DUMMY_SP,
prefix: false,
op: op!("++"),
arg: Box::new(keys_index.clone().into()),
}View on GitHub (pinned to 5176682b65)
Solutions
- Put explicit_resource_management() before generator()/for_of() in your chain.
- Use preset_env/CompatEnv (correct ordering guaranteed).
- Unify swc versions via a single swc_core release.
- Avoid `using` in for-of heads until wired.
Example fix
// before
let pass = Chain::new(swc_ecma_compat_es2015::generator());
// after
let pass = Chain::new(
swc_ecma_transforms_proposal::explicit_resource_management(),
swc_ecma_compat_es2015::generator(),
); Defensive patterns
Strategy: validation
Validate before calling
// Reuse the ForHead scan before generator conversion
use swc_ecma_visit::{Visit, VisitWith};
struct UsingHead(bool); impl Visit for UsingHead {
fn visit_for_head(&mut self, h: &ForHead) {
self.0 |= matches!(h, ForHead::UsingDecl(_)); h.visit_children_with(self);
}
}
// if UsingHead found anything, prepend explicit_resource_management() Prevention
- Gate `using` syntax in the parser on the presence of its lowering pass.
- Include generator-function fixtures containing for-of in CI.
- Use CompatEnv/preset_env pipelines for ES5 targets.
When it happens
Trigger: A for-of loop with a `using` head inside a generator or async function, compiled by a chain that includes es2015::generator but not explicit_resource_management.
Common situations: TS 5.2+ `using` syntax compiled to ES5 through custom swc_core pipelines; bundler plugins assembling compat passes by hand; swc_core version mismatch omitting the proposal pass.
Related errors
- using declaration must be removed by previous pass
- spread should be removed before applying generator
- object rest pattern should be removed by es2018::object_rest
- 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/718b67c2057acfe7.
Report an issue: GitHub.