swc-project/swc · error

Fast-path injection for Fold / VisitMut where pattern is…

Error message

Fast-path injection for Fold / VisitMut where pattern is not an ident

What it means

Compile-time panic from the #[fast_path] proc macro (swc_ecma_transforms_macros). When injecting the should_work fast-path check into a Fold/VisitMut impl method, the macro must reference the node argument by name in generated code (e.g. should_work::<C,_>(&arg)), so the parameter has to be a simple identifier binding. If the annotated method declares the node parameter with any other pattern (wildcard, tuple, ref-pattern), macro expansion aborts with unimplemented!.

Solutions

  1. Change the node parameter to a plain identifier binding, e.g. `fn visit_mut_ident(&mut self, n: &mut Ident)`
  2. Never use `_`, tuple, or ref patterns for the node parameter of methods in a #[fast_path]-annotated impl
  3. If the signature must stay as-is, remove the #[fast_path] attribute from that impl

Example fix

// before
#[fast_path]
impl VisitMut for MyVisitor {
    fn visit_mut_ident(&mut self, _: &mut Ident) { /* ... */ }
}

// after
#[fast_path]
impl VisitMut for MyVisitor {
    fn visit_mut_ident(&mut self, n: &mut Ident) { /* ... */ }
}
Defensive patterns

Strategy: validation

Validate before calling

// Before shipping, lint the annotated impl: every method parameter
// in a #[fast_path] impl must be a plain ident binding.
// Quick manual check (no runtime API exists — this is compile time):
// rg -n '#[fast_path]' -A 8 | grep -E 'fn .+\(&mut self, (_|\(|&)'
// Any hit is a candidate for this panic.

Prevention

When it happens

Trigger: Applying #[fast_path] to an impl Fold/VisitMut block whose method (typically fold_ident/visit_mut_ident) uses `fn visit_mut_ident(&mut self, _: &mut Ident)`, a tuple pattern, or a ref/destructuring pattern instead of a plain `n: &mut Ident` binding.

Common situations: Writing a custom swc visitor crate and reformatting or auto-completing method signatures until the parameter becomes `_` or a non-ident pattern; copying a #[fast_path] example into code that uses wildcard parameter names.

Related errors


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

Appendix: source

Thrown at crates/swc_ecma_transforms_macros/src/fast.rs:106

        let ty_arg = m
            .sig
            .inputs
            .last()
            .expect("method of Fold / VisitMut must accept two parameters");
        let ty_arg = match ty_arg {
            FnArg::Receiver(_) => unreachable!(),
            FnArg::Typed(ty) => ty,
        };
        if m.sig.ident == "visit_mut_ident" || m.sig.ident == "fold_ident" {
            return m;
        }
        if m.block.stmts.is_empty() {
            return m;
        }

        let arg = match &*ty_arg.pat {
            Pat::Ident(i) => &i.ident,
            _ => unimplemented!(
                "Fast-path injection for Fold / VisitMut where pattern is not an ident"
            ),
        };

        let checker = &self.handler;

        let fast_path = match self.mode {
            Mode::Fold => parse_quote!(
                if !swc_ecma_transforms_base::perf::should_work::<#checker, _>(&#arg) {
                    return #arg;
                }
            ),
            Mode::VisitMut => parse_quote!(
                if !swc_ecma_transforms_base::perf::should_work::<#checker, _>(&*#arg) {
                    return;
                }
            ),
        };

View on GitHub (pinned to 5176682b65)