{"record":{"id":"17f1baeb1f2e5be9","repo":"slint-ui/slint","slug":"only-supported-for-structure-with-named-fields","errorCode":null,"errorMessage":"Only supported for structure with named fields","messagePattern":"Only supported for structure with named fields","errorType":"exception","errorClass":"proc_macro::Error","httpStatus":null,"severity":"error","filePath":"helper_crates/vtable/macro/macro.rs","lineNumber":173,"sourceCode":"    // access to the vtable through the get_vtable() function\n    assert_eq!(animal_vref.get_vtable().LEG_NUMBER, 4);\n    // functions are also added for the #[field_offset] member\n    assert_eq!(*animal_vref.IS_HUNGRY(), false);\n    *animal_vref.IS_HUNGRY_mut() = true;\n}\nassert_eq!(dog.is_hungry, true);\n```\n\n\n*/\n#[proc_macro_attribute]\npub fn vtable(_attr: TokenStream, item: TokenStream) -> TokenStream {\n    let mut input = parse_macro_input!(item as ItemStruct);\n\n    let fields = if let Fields::Named(fields) = &mut input.fields {\n        fields\n    } else {\n        return Error::new(\n            proc_macro2::Span::call_site(),\n            \"Only supported for structure with named fields\",\n        )\n        .to_compile_error()\n        .into();\n    };\n\n    let vtable_name = input.ident.to_string();\n    if !vtable_name.ends_with(\"VTable\") {\n        return Error::new(input.ident.span(), \"The structure does not ends in 'VTable'\")\n            .to_compile_error()\n            .into();\n    }\n\n    let trait_name = Ident::new(&vtable_name[..vtable_name.len() - 6], input.ident.span());\n    let to_name = quote::format_ident!(\"{}TO\", trait_name);\n    let module_name = quote::format_ident!(\"{}_vtable_mod\", trait_name);\n    let static_vtable_macro_name = quote::format_ident!(\"{}_static\", vtable_name);","sourceCodeStart":155,"sourceCodeEnd":191,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/helper_crates/vtable/macro/macro.rs#L155-L191","documentation":"The #[vtable] proc macro only supports structs with named fields, because it generates offset accessors and constructors per field name. Applying #[vtable] to a tuple struct or unit struct causes this compile error at the macro call site.","triggerScenarios":"Annotating `struct FooVTable();`, `struct FooVTable(fn(), usize);` (tuple struct) or a unit struct `struct FooVTable;` with #[vtable].","commonSituations":"Copy-pasting a plain struct pattern when defining a new vtable; converting an existing tuple-struct of function pointers to the vtable macro system without converting to named fields.","solutions":["Convert the struct to named fields, one per function pointer / data member.","If you don't need vtable machinery, remove the #[vtable] attribute."],"exampleFix":"// before\n#[vtable]\nstruct FooVTable(*const c_void, fn(*const FooVTable, *mut u8));\n// after\n#[vtable]\nstruct FooVTable {\n    drop_in_place: unsafe fn(VRefMut<FooVTable>),\n    do_thing: fn(VRef<FooVTable>, u8),\n}","handlingStrategy":"validation","validationCode":"// ensure named fields before applying the macro\nstruct FooVTable { drop_in_place: unsafe fn(VRefMut<FooVTable>), }","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Only apply #[vtable] to structs you have written with named fields.","Let the compiler catch it — this error appears at macro expansion; fix immediately by restructuring fields."],"tags":["proc-macro","compile-time","rust"],"backgroundTag":"invalid-argument-value","analyzedSha":"bb937076de3f7919766c1f25e2e969367cf77e9a","analyzedAt":"2026-09-16T01:37:20.251Z","contentChangedAt":"2026-09-16T01:37:20.251Z","schemaVersion":2},"datasetVersion":"2026-09-23T08:17:48.524Z"}