{"record":{"id":"591daaa4cc970730","repo":"swc-project/swc","slug":"err","errorCode":null,"errorMessage":"{err:?}","messagePattern":"\\{err:\\?\\}","errorType":"exception","errorClass":"anyhow::Error","httpStatus":null,"severity":"error","filePath":"crates/swc_ecma_quote_macros/src/ret_type.rs","lineNumber":75,"sourceCode":"fn parse<T>(\n    input_str: &str,\n    op: &mut dyn FnMut(&mut Parser<Lexer>) -> PResult<T>,\n) -> Result<BoxWrapper, Error>\nwhere\n    T: ToCode,\n{\n    let cm = Lrc::new(SourceMap::default());\n    let fm = cm.new_source_file(FileName::Anon.into(), input_str.to_string());\n\n    let lexer = Lexer::new(\n        Default::default(),\n        EsVersion::Es2020,\n        StringInput::from(&*fm),\n        None,\n    );\n    let mut parser = Parser::new_from(lexer);\n    op(&mut parser)\n        .map_err(|err| anyhow!(\"{err:?}\"))\n        .with_context(|| format!(\"failed to parse input as `{}`\", type_name::<T>()))\n        .map(|val| BoxWrapper(Box::new(val)))\n}\n\nfn extract_generic<'a>(name: &str, ty: &'a Type) -> Option<&'a Type> {\n    if let Type::Path(p) = ty {\n        let last = p.path.segments.last().unwrap();\n\n        if !last.arguments.is_empty() && last.ident == name {\n            match &last.arguments {\n                PathArguments::AngleBracketed(tps) => {\n                    let arg = tps.args.first().unwrap();\n\n                    match arg {\n                        GenericArgument::Type(arg) => return Some(arg),\n                        _ => unimplemented!(\"generic parameter other than type\"),\n                    }\n                }","sourceCodeStart":57,"sourceCodeEnd":93,"githubUrl":"https://github.com/swc-project/swc/blob/d7d74346665e36e692aa07e13d4ee3ee692ee35c/crates/swc_ecma_quote_macros/src/ret_type.rs#L57-L93","documentation":"Compile-time error from swc_ecma_quote_macros: the tokens passed to a quote_*! macro could not be parsed as the expected Rust type T (an SWC AST node). The anyhow error wraps the parser's debug-formatted error and the with_context layer adds 'failed to parse input as `<T>`'. It fires during proc-macro expansion, so it breaks the build of the crate using the macro.","triggerScenarios":"Using quote_expr!, quote_stmt!, quote_ident!, quote_type!, etc. with token soup that is not a valid single production of the target AST type - e.g. two expressions where one is expected, statements passed to quote_expr!, reserved words used as identifiers, or TS-only syntax inside a macro targeting an ECMAScript node.","commonSituations":"Writing transforms that embed JS snippets via quote macros; refactoring a quoted snippet so it is no longer a single valid expression/statement; copy-pasting multiline JS into a macro that expects one node.","solutions":["Make the quoted content exactly one valid instance of the macro's target type (one expression for quote_expr!, one statement for quote_stmt!, ...)","Wrap multiple items appropriately or split into several macro invocations","Check the macro name against the content - statements/declarations do not parse as expressions","Read the {err:?} payload: it names the unexpected token"],"exampleFix":"// before: two expressions inside quote_expr!\nlet e = quote_expr!(&ctx, foo() bar());\n\n// after: a single expression\nlet e = quote_expr!(&ctx, foo());","handlingStrategy":"validation","validationCode":"// Rust: validate quoted snippets during development with a test\n// that expands the macro and asserts it parses\n#[test]\nfn quoted_snippets_parse() {\n    let _ = quote_expr!(&ctx, foo() + 1);   // compile of the test itself is the validation\n    let _ = quote_stmt!(&ctx, let x = 1;);\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["One macro = one AST node; split multi-node snippets across macros","Match the macro suffix to content kind (expr/stmt/ident/type) before writing tokens","CI-compile all crates containing quote macros so drift fails the build early"],"tags":["swc","macros","compile-time","parser","quote"],"backgroundTag":null,"analyzedSha":"d7d74346665e36e692aa07e13d4ee3ee692ee35c","analyzedAt":"2026-08-16T12:41:13.160Z","schemaVersion":2},"datasetVersion":"2026-08-16T13:17:31.715Z"}