{"record":{"id":"9212acc145292812","repo":"risingwavelabs/risingwave","slug":"type-inference-for-this-function-should-be-special","errorCode":null,"errorMessage":"type inference for this function should be specially handled in frontend, and should not call sig.type_infer","messagePattern":"type inference for this function should be specially handled in frontend, and should not call sig\\.type_infer","errorType":"panic","errorClass":null,"httpStatus":null,"severity":"error","filePath":"src/expr/macro/src/gen.rs","lineNumber":84,"sourceCode":"            if ret == \"auto\" {\n                ret = types::min_compatible_type(&args);\n            }\n            let attr = FunctionAttr {\n                args: args.iter().map(|s| s.to_string()).collect(),\n                ret: ret.to_owned(),\n                ..self.clone()\n            };\n            attrs.push(attr);\n        }\n        attrs\n    }\n\n    /// Generate the type infer function: `fn(&[DataType]) -> Result<DataType>`\n    fn generate_type_infer_fn(&self) -> Result<TokenStream2> {\n        if let Some(func) = &self.type_infer {\n            if func == \"unreachable\" {\n                return Ok(\n                    quote! { |_| unreachable!(\"type inference for this function should be specially handled in frontend, and should not call sig.type_infer\") },\n                );\n            }\n            // use the user defined type inference function\n            return Ok(func.parse().unwrap());\n        } else if self.ret == \"any\" {\n            // TODO: if there are multiple \"any\", they should be the same type\n            if let Some(i) = self.args.iter().position(|t| t == \"any\") {\n                // infer as the type of \"any\" argument\n                return Ok(quote! { |args| Ok(args[#i].clone()) });\n            }\n            if let Some(i) = self.args.iter().position(|t| t == \"anyarray\") {\n                // infer as the element type of \"anyarray\" argument\n                return Ok(quote! { |args| Ok(args[#i].as_list_elem().clone()) });\n            }\n        } else if self.ret == \"anyarray\" {\n            if let Some(i) = self.args.iter().position(|t| t == \"anyarray\") {\n                // infer as the type of \"anyarray\" argument\n                return Ok(quote! { |args| Ok(args[#i].clone()) });","sourceCodeStart":66,"sourceCodeEnd":102,"githubUrl":"https://github.com/risingwavelabs/risingwave/blob/6469eb736d691e8e9b8a419a57edd6429ca77417/src/expr/macro/src/gen.rs#L66-L102","documentation":"The `#[define_function!]`-style macro lets authors mark a function's type inference as `type_infer = \"unreachable\"`, generating a closure that panics if invoked. This panic message signals that the function's return type must be inferred by the frontend and `sig.type_infer` must never be called at runtime.","triggerScenarios":"Calling type inference at runtime on a function descriptor generated with `type_infer = \"unreachable\"` — i.e. a function whose return type depends on arguments (e.g. casts, array elem access) that the frontend must resolve specially.","commonSituations":"Adding a new function with `unreachable` inference but forgetting to register frontend type inference; batch/stream executor falling back to generic inference for such a function.","solutions":["Implement frontend type inference for this function so the backend infer path is never used","Change the macro declaration to provide a real `type_infer = \"|args| Ok(...)\"` closure","Trace the caller of sig.type_infer and route it to the frontend-specialized path"],"exampleFix":"// before\nTypeInfer::Unreachable\n// after\nTypeInfer::from_closure(|args| Ok(DataType::Varchar)) // or implement frontend inference","handlingStrategy":"validation","validationCode":"// before registering a function with type_infer = \"unreachable\", assert the frontend infers its type:\nassert!(frontend_infer_return_type(func_id, arg_types).is_ok(), \"frontend must infer this function's type\");","typeGuard":null,"tryCatchPattern":"match sig.type_infer(args) {\n    Err(e) if e.to_string().contains(\"specially handled in frontend\") => frontend_infer_return_type(func_id, args),\n    other => other,\n}","preventionTips":["Pair every `unreachable` type_infer declaration with a frontend inference rule","Add a lint/test that all functions in the registry are inferable by the frontend","Never call sig.type_infer for frontend-special functions"],"tags":["macro","type-inference","proc-macro"],"backgroundTag":"method-not-implemented","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"}