{"record":{"id":"606602d4a17d5ede","repo":"pydantic/monty","slug":"vectorcall-requires-the-default-clinic-style-plus-at-most","errorCode":null,"errorMessage":"`vectorcall` requires the default `clinic` style plus `at_most_total` — it models a `tp_vectorcall` fast path in front of a clinic parser","messagePattern":"`vectorcall` requires the default `clinic` style plus `at_most_total` — it models a `tp_vectorcall` fast path in front of a clinic parser","errorType":"validation","errorClass":"syn::Error","httpStatus":null,"severity":"error","filePath":"crates/monty-macros/src/from_args.rs","lineNumber":254,"sourceCode":"            Style::Clinic | Style::C | Style::CNamed => {}\n        }\n\n        if self.at_most_total {\n            if matches!(self.style, Style::Def | Style::Unpack) {\n                return err(\n                    \"`at_most_total` cannot be combined with `style = def` or `style = unpack` \\\n                     — the total pre-count models `PyArg_ParseTupleAndKeywords`-family C parsers\",\n                );\n            }\n            if self.varargs_idx.is_some() || self.varkwargs_idx.is_some() {\n                return err(\"`at_most_total` cannot be combined with `varargs` or `varkwargs` \\\n                     — the up-front total-count check is only meaningful for \\\n                     signatures with a fixed maximum\");\n            }\n        }\n\n        if self.vectorcall && !(self.at_most_total && self.style == Style::Clinic) {\n            return err(\"`vectorcall` requires the default `clinic` style plus `at_most_total` \\\n                 — it models a `tp_vectorcall` fast path in front of a clinic parser\");\n        }\n\n        if self.kwarg_error_name.is_some() && !matches!(self.style, Style::Def | Style::Clinic | Style::Unpack) {\n            return err(\"`kwarg_error_name` is only meaningful with `style = def`, the default \\\n                 `clinic` style, or `style = unpack` (where it names the function in the \\\n                 `takes no keyword arguments` error) — the C families defer unknown-kwarg \\\n                 errors past binding\");\n        }\n\n        if self.kwargs_not_supported_yet {\n            if self.varkwargs_idx.is_some() {\n                return err(\"`kwargs_not_supported_yet` cannot be combined with `varkwargs` \\\n                     — the flag rejects every kwarg up front, so there's nothing to collect\");\n            }\n            if self.fields.iter().any(|f| matches!(f.kind, FieldKind::KwOnly)) {\n                return err(\"`kwargs_not_supported_yet` cannot be combined with `kw_only` fields \\\n                     — the flag rejects every kwarg up front, so kw_only slots are unreachable\");","sourceCodeStart":236,"sourceCodeEnd":272,"githubUrl":"https://github.com/pydantic/monty/blob/adc986b362e3961f407868cb118a99fe831b9e61/crates/monty-macros/src/from_args.rs#L236-L272","documentation":"The `vectorcall` flag was used without the exact supporting configuration. `vectorcall` models a `tp_vectorcall` fast path in front of a clinic parser, which requires the default `clinic` style together with `at_most_total`; any other combination is rejected at compile time because the generated fast path would not line up with the parser.","triggerScenarios":"Compiling `#[derive(FromArgs)] #[from_args(vectorcall)]` with either `at_most_total` missing or the style set to something other than `clinic` (e.g. `style = \"c\"`). Checked in `Signature::validate` (crates/monty-macros/src/from_args.rs:253-256).","commonSituations":"Adding `vectorcall` for a hot-path optimization to an existing struct that uses a non-clinic style or lacks `at_most_total`; copying the flag from a struct that already had the full `clinic + at_most_total` setup.","solutions":["Remove `vectorcall` unless the call is hot enough to need the fast path.","If the fast path is needed, use the default `clinic` style and add `at_most_total` so the combination is `#[from_args(at_most_total, vectorcall)]`.","Do not add `vectorcall` to structs with `style = \"c\"`, `\"c_named\"`, `\"def\"`, or `\"unpack\"`; only clinic-style parsers sit behind the vectorcall front."],"exampleFix":"// before\n#[derive(FromArgs)]\n#[from_args(style = \"c\", vectorcall)]\nstruct Args { a: i64 }\n\n// after\n#[derive(FromArgs)]\n#[from_args(at_most_total, vectorcall)]\nstruct Args { a: i64 }","handlingStrategy":"validation","validationCode":"// vectorcall demands the exact pair clinic + at_most_total:\nfn vectorcall_ok(style: &str, at_most_total: bool, vectorcall: bool) -> bool {\n    !vectorcall || (at_most_total && style == \"clinic\")\n}","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Add vectorcall only to hot-path functions already using at_most_total + default clinic style.","Treat vectorcall as an optimization, not a default: measure before adding it."],"tags":["rust","proc-macro","fromargs","compile-time"],"backgroundTag":"missing-required-flag","analyzedSha":"adc986b362e3961f407868cb118a99fe831b9e61","analyzedAt":"2026-09-13T19:19:18.698Z","contentChangedAt":"2026-09-13T19:19:18.698Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}