{"record":{"id":"12320d91354c58da","repo":"swc-project/swc","slug":"unknown-visitor-type","errorCode":null,"errorMessage":"Unknown visitor type: {:?}","messagePattern":"Unknown visitor type: (.+?)","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_transforms_macros/src/parallel.rs","lineNumber":16,"sourceCode":"#![allow(non_snake_case)]\n\nuse proc_macro2::{Span, TokenStream};\nuse syn::{parse_quote, Expr, Ident, ImplItem, ImplItemFn, ItemImpl, Meta, Type};\n\nuse crate::common::Mode;\n\npub fn expand(attr: TokenStream, mut item: ItemImpl) -> ItemImpl {\n    let mode = {\n        let p = &item.trait_.as_ref().unwrap().1;\n        if p.is_ident(\"Fold\") {\n            Mode::Fold\n        } else if p.is_ident(\"VisitMut\") {\n            Mode::VisitMut\n        } else {\n            unimplemented!(\"Unknown visitor type: {:?}\", p)\n        }\n    };\n    let meta = if attr.is_empty() {\n        None\n    } else {\n        Some(syn::parse2::<Meta>(attr).expect(\"failed to parse meta\"))\n    };\n    let explode = meta\n        .as_ref()\n        .map(|v| v.path().is_ident(\"explode\"))\n        .unwrap_or(false);\n\n    item.items.push(ImplItem::Fn(make_par_visit_method(\n        mode,\n        \"module_items\",\n        explode,\n    )));\n    item.items","sourceCodeStart":1,"sourceCodeEnd":34,"githubUrl":"https://github.com/swc-project/swc/blob/5176682b65416c6b5de6b47379ae1588ea3ecb3f/crates/swc_ecma_transforms_macros/src/parallel.rs#L1-L34","documentation":"The #[parallel] proc macro (swc_ecma_transforms_macros) works only on impl blocks for the Fold or VisitMut traits; it inspects the trait path segment to pick a Mode. When the impl is for any other trait, expansion aborts with `unimplemented!(\"Unknown visitor type\")`. Note that an inherent impl (no trait at all) panics even earlier on `item.trait_.as_ref().unwrap()`.","triggerScenarios":"Annotating an impl block with #[parallel] where the trait is neither Fold nor VisitMut, e.g. `#[parallel] impl Visit for MyVisitor { ... }` or `#[parallel] impl MyTrait for X { ... }`.","commonSituations":"Porting a visitor from the deprecated Visit trait (or a custom trait) to the parallel helpers, or applying #[parallel] by copy-paste onto an unrelated impl block.","solutions":["Implement and annotate the Fold or VisitMut trait instead: `#[parallel] impl VisitMut for MyVisitor { ... }`","If you need parallel traversal for another trait, hand-write the rayon-based loop instead of using the macro","Remove the #[parallel] attribute if parallelism is not required"],"exampleFix":"// before\n#[parallel]\nimpl Visit for MyVisitor {\n    // ...\n}\n\n// after\n#[parallel]\nimpl VisitMut for MyVisitor {\n    // ...\n}","handlingStrategy":"validation","validationCode":"// Validate the impl target before annotating (compile-time review):\n// the trait path's last segment must be exactly `Fold` or `VisitMut`.\nconst SUPPORTED = new Set(['Fold', 'VisitMut']);\nconst traitName = implNode.traitPath.lastSegment.identifier; // pseudo\nif (!SUPPORTED.has(traitName)) throw new Error('#[parallel] supports Fold/VisitMut only');","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Reserve #[parallel] for impl Fold / impl VisitMut blocks","Run cargo check right after moving or renaming traits in visitor code","Keep the attribute adjacent to the impl line so refactors do not silently move it onto other impls"],"tags":["proc-macro","swc","rust","compile-time","parallel","visitor"],"backgroundTag":"proc-macro-unsupported-input","analyzedSha":"5176682b65416c6b5de6b47379ae1588ea3ecb3f","analyzedAt":"2026-08-17T16:16:52.067Z","contentChangedAt":"2026-08-17T16:16:52.067Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}