swc-project/swc · error

Unknown quote type: {ty:?}

Error message

Unknown quote type: {ty:?}

What it means

swc_ecma_quote_macros' quote! proc macro parses its first argument as a string naming the AST node type to parse the quoted code into (e.g. "Expr", "Stmt", "Module", "ModuleItem", "AssignTarget"). The macro matches that literal against a fixed list; any string not in the list falls through to bail!('Unknown quote type: {ty:?}'), surfacing as a compile-time macro error.

Source

Thrown at crates/swc_ecma_quote_macros/src/ret_type.rs:54

    if let Type::Path(p) = ty {
        if let Some(ident) = p.path.get_ident() {
            match &*ident.to_string() {
                "Expr" => return parse(input_str, &mut |p| p.parse_expr().map(|v| *v)),
                "Pat" => return parse(input_str, &mut |p| p.parse_pat()),
                "Stmt" => return parse(input_str, &mut |p| p.parse_stmt_list_item()),
                "AssignTarget" => {
                    return parse(input_str, &mut |p| {
                        Ok(AssignTarget::try_from(p.parse_pat()?)
                            .expect("failed to parse AssignTarget"))
                    })
                }
                "ModuleItem" => return parse(input_str, &mut |p| p.parse_module_item()),
                _ => {}
            }
        }
    }

    bail!("Unknown quote type: {ty:?}");
}

fn parse<T>(
    input_str: &str,
    op: &mut dyn FnMut(&mut Parser<Lexer>) -> PResult<T>,
) -> Result<BoxWrapper, Error>
where
    T: ToCode,
{
    let cm = Lrc::new(SourceMap::default());
    let fm = cm.new_source_file(FileName::Anon.into(), input_str.to_string());

    let lexer = Lexer::new(
        Default::default(),
        EsVersion::Es2020,
        StringInput::from(&*fm),
        None,
    );

View on GitHub (pinned to 5176682b65)

Solutions

  1. Use one of the supported type literals for your macro version (Expr, Stmt, Module, ModuleItem, AssignTarget, etc.); check the match statement in ret_type.rs of the version you depend on
  2. For unsupported types, parse into the closest supported type and convert afterwards (e.g. quote to Expr, then convert with TryFrom/TryInto)
  3. Upgrade swc_ecma_quote_macros to a version that supports your type
  4. Verify the type string is spelled and cased exactly as in the supported list

Example fix

// before
let p = quote!("Param", "$arg: ident"); // Param not supported

// after: parse as a supported type, then convert
let e: Param = quote!("Pat", "$arg") .try_into()?; // or use a supported node type directly
Defensive patterns

Strategy: validation

Validate before calling

// Compile-time: assert the type literal is in the set supported by your macro version.
// Supported set (check ret_type.rs for your version), e.g.:
const SUPPORTED: &[&str] = &["Expr", "Stmt", "Module", "ModuleItem", "AssignTarget" /* ... */];
// const _: () = assert!(SUPPORTED.contains(&"Expr")); // Rust has no const str contains; rely on the macro error and fix the literal

Prevention

When it happens

Trigger: Writing quote!("Param", "$p") or any type name outside the supported set; passing a type alias or newly added swc_ast node name that the macro version does not recognize yet; a typo in the type string, including casing mistakes.

Common situations: Upgrading swc_ecma_quote_macros where supported types changed; copy-pasting quote! calls from code targeting a newer/older macro version; using a node type that exists in swc_ecma_ast but was never wired into the quote macro.

Related errors


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