{"record":{"id":"d74727923f4af5aa","repo":"swc-project/swc","slug":"using-declaration-must-be-removed-by-previous-pass","errorCode":null,"errorMessage":"using declaration must be removed by previous pass","messagePattern":"using declaration must be removed by previous pass","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_compat_es2015/src/destructuring.rs","lineNumber":124,"sourceCode":"                        return;\n                    }\n                    _ => {\n                        let left_ident = make_ref_ident_for_for_stmt();\n                        let left = ForHead::Pat(left_ident.clone().into());\n                        // Unpack variables\n                        let stmt = AssignExpr {\n                            span: DUMMY_SP,\n                            left: pat.take().try_into().unwrap(),\n                            op: op!(\"=\"),\n                            right: Box::new(left_ident.into()),\n                        }\n                        .into_stmt();\n                        (left, stmt)\n                    }\n                },\n\n                ForHead::UsingDecl(..) => {\n                    unreachable!(\"using declaration must be removed by previous pass\")\n                }\n\n                #[cfg(swc_ast_unknown)]\n                _ => panic!(\"unable to access unknown nodes\"),\n            };\n\n            for_stmt.left = left;\n\n            for_stmt.body = Box::new(Stmt::Block(match &mut *for_stmt.body {\n                Stmt::Block(BlockStmt { span, stmts, ctxt }) => BlockStmt {\n                    span: *span,\n                    stmts: iter::once(stmt).chain(stmts.take()).collect(),\n                    ctxt: *ctxt,\n                },\n                body => BlockStmt {\n                    stmts: vec![stmt, body.take()],\n                    ..Default::default()\n                },","sourceCodeStart":106,"sourceCodeEnd":142,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_compat_es2015/src/destructuring.rs#L106-L142","documentation":"The es2015 destructuring pass rewrites for-of/for-in loop heads. `for (using x of y)` (explicit resource management) must already be lowered to plain declarations by swc_ecma_transforms_proposal::explicit_resource_management; when destructuring encounters ForHead::UsingDecl it panics because it has no lowering for it. The pass ordering contract was violated.","triggerScenarios":"Running swc_ecma_compat_es2015::destructuring directly (or a hand-assembled chain missing the explicit-resource-management pass) on code containing `for (using res of iterable)` or `for await (using res of asyncIterable)`.","commonSituations":"Enabling the explicitResourceManagement parser feature but assembling compat passes manually; targeting ES2015 with a custom pass list after swc added `using` support; old pipelines replayed against newer sources.","solutions":["Use the full compat preset (swc core build/CompatibleWith targets) so the explicit-resource-management lowering runs before destructuring","In a manual chain, insert swc_ecma_transforms_proposal::explicit_resource_management ahead of es2015 destructuring","Avoid `using` declarations in for-of heads when you control the pass list, or pre-transpile them"],"exampleFix":"// before (custom chain, missing the lowering pass)\nlet passes = vec![destructuring()];\n\n// after\nlet passes = vec![\n  Box::new(swc_ecma_transforms_proposal::explicit_resource_management()),\n  destructuring(),\n];","handlingStrategy":"validation","validationCode":"// Detect `using` declarations before running a partial es2015 chain\nlet uses_using = regex::Regex::new(\n    r#\"(?:^|;|\\{)\\s*using\\s+[A-Za-z_$]|for\\s*\\(?:?\\s*(?:await\\s+)?using\\s+\"#,\n).unwrap();\nif uses_using.is_match(&source) {\n    return Err(\"explicit_resource_management pass must run before destructuring\".into());\n}","typeGuard":null,"tryCatchPattern":"if let Err(p) = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| destructuring(&mut program))) {\n    if panic_message(&p).contains(\"using declaration\") {\n        // fix chain: insert explicit_resource_management() before destructuring and retry\n    } else { std::panic::resume_unwind(p); }\n}","preventionTips":["Rely on swc's full compat preset ordering rather than hand-picked passes","When adding new syntax features (like `using`), update the pass chain in the same change","Smoke-test the pipeline on sources that use every enabled parser feature"],"tags":["swc","compat","es2015","using-declarations","pass-order"],"backgroundTag":"using-declaration-lowering","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}