{"record":{"id":"52d9eb8050dfc950","repo":"risingwavelabs/risingwave","slug":"invalid-prebuild-syntax","errorCode":null,"errorMessage":"invalid prebuild syntax","messagePattern":"invalid prebuild syntax","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/macro/src/gen.rs","lineNumber":287,"sourceCode":"            \"T\" | \"T1\" | \"T2\" | \"T3\" => format!(\": Option<{}>\", types::owned_type(&self.ret))\n                .parse()\n                .unwrap(),\n            _ => quote! {},\n        };\n        let ret_array_type = format_ident!(\"{}\", types::array_type(&self.ret));\n        let builder_type = format_ident!(\"{}Builder\", types::array_type(&self.ret));\n        let prebuilt_arg_type = match &self.prebuild {\n            Some(s) if optimize_const => s.split(\"::\").next().unwrap().parse().unwrap(),\n            _ => quote! { () },\n        };\n        let prebuilt_arg_value = match &self.prebuild {\n            // example:\n            // prebuild = \"RegexContext::new($1)\"\n            // return = \"RegexContext::new(i1)\"\n            Some(s) => s\n                .replace('$', \"i\")\n                .parse()\n                .expect(\"invalid prebuild syntax\"),\n            None => quote! { () },\n        };\n        let prebuild_const = if self.prebuild.is_some() && optimize_const {\n            let build_general = self.generate_build_scalar_function(user_fn, false)?;\n            quote! {{\n                let build_general = #build_general;\n                #(\n                    // try to evaluate constant for prebuilt arguments\n                    let #prebuilt_inputs = match children[#prebuilt_indices].eval_const() {\n                        Ok(s) => s,\n                        // prebuilt argument is not constant, fallback to general\n                        Err(_) => return build_general(return_type, children),\n                    };\n                    // get reference to the constant value\n                    let #prebuilt_inputs = match &#prebuilt_inputs {\n                        Some(s) => s.as_scalar_ref_impl().try_into()?,\n                        // the function should always return null if any const argument is null\n                        None => return Ok(risingwave_expr::expr::LiteralExpression::new(","sourceCodeStart":269,"sourceCodeEnd":305,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/macro/src/gen.rs#L269-L305","documentation":"The macro's `prebuild` option accepts an expression template where `$1`, `$2` map to argument variables `i1`, `i2`. The string is rewritten and parsed as Rust TokenStream; if the expression does not parse, the macro panics with `invalid prebuild syntax` at proc-macro expansion time.","triggerScenarios":"Specifying e.g. `prebuild = \"RegexContext::new($1)\"` with a syntax error, an unbalanced delimiter, or a stray `$n`/identifier that yields invalid Rust tokens after replacement.","commonSituations":"Typo in a prebuild expression like `RegexContext:new($1)`; referencing a nonexistent `$3` producing identifiers like `i3` out of scope; hand-editing prebuild strings.","solutions":["Fix the prebuild expression so it is valid Rust after `$`->`i` replacement","Ensure only `$1..$n` placeholders matching actual arguments are used","Replace the `.expect` with a proper proc-macro `syn::Error` for a better message"],"exampleFix":"// before\nprebuild = \"RegexContext::new($1 $2)\"\n// after\nprebuild = \"RegexContext::new($1, $2)\"","handlingStrategy":"validation","validationCode":"// validate prebuild parses before feeding to macro (mentally or in a test):\nlet expr: proc_macro2::TokenStream = \"RegexContext::new($1)\".replace('$', \"i\").parse().expect(\"invalid prebuild syntax\");","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Test proc-macro expansion with `cargo expand` when adding prebuild","Only use $1..$n placeholders matching declared arguments","Keep prebuild expressions minimal and well-formed Rust"],"tags":["proc-macro","prebuild","syntax"],"backgroundTag":"invalid-argument-format","analyzedSha":"6469eb736d691e8e9b8a419a57edd6429ca77417","analyzedAt":"2026-09-11T21:06:21.487Z","contentChangedAt":"2026-09-11T21:06:21.487Z","schemaVersion":2},"datasetVersion":"2026-09-14T16:17:12.679Z"}