slint-ui/slint · error · proc_macro::Error
Only supported for structure with named fields
Error message
Only supported for structure with named fields
What it means
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.
Solutions
- Convert the struct to named fields, one per function pointer / data member.
- If you don't need vtable machinery, remove the #[vtable] attribute.
Example fix
// before
#[vtable]
struct FooVTable(*const c_void, fn(*const FooVTable, *mut u8));
// after
#[vtable]
struct FooVTable {
drop_in_place: unsafe fn(VRefMut<FooVTable>),
do_thing: fn(VRef<FooVTable>, u8),
} Defensive patterns
Strategy: validation
Validate before calling
// ensure named fields before applying the macro
struct FooVTable { drop_in_place: unsafe fn(VRefMut<FooVTable>), } Prevention
- 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.
When it happens
Trigger: Annotating `struct FooVTable();`, `struct FooVTable(fn(), usize);` (tuple struct) or a unit struct `struct FooVTable;` with #[vtable].
Common situations: 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.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- Self pointer need to be the first
- The structure does not ends in 'VTable'
- The type of an #[field_offset] member in the vtable must be…
- VTable cannot be mutable
- VTable pointer need to be the first
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/17f1baeb1f2e5be9.
Report an issue: GitHub.
Appendix: source
Thrown at helper_crates/vtable/macro/macro.rs:173
// access to the vtable through the get_vtable() function
assert_eq!(animal_vref.get_vtable().LEG_NUMBER, 4);
// functions are also added for the #[field_offset] member
assert_eq!(*animal_vref.IS_HUNGRY(), false);
*animal_vref.IS_HUNGRY_mut() = true;
}
assert_eq!(dog.is_hungry, true);
```
*/
#[proc_macro_attribute]
pub fn vtable(_attr: TokenStream, item: TokenStream) -> TokenStream {
let mut input = parse_macro_input!(item as ItemStruct);
let fields = if let Fields::Named(fields) = &mut input.fields {
fields
} else {
return Error::new(
proc_macro2::Span::call_site(),
"Only supported for structure with named fields",
)
.to_compile_error()
.into();
};
let vtable_name = input.ident.to_string();
if !vtable_name.ends_with("VTable") {
return Error::new(input.ident.span(), "The structure does not ends in 'VTable'")
.to_compile_error()
.into();
}
let trait_name = Ident::new(&vtable_name[..vtable_name.len() - 6], input.ident.span());
let to_name = quote::format_ident!("{}TO", trait_name);
let module_name = quote::format_ident!("{}_vtable_mod", trait_name);
let static_vtable_macro_name = quote::format_ident!("{}_static", vtable_name);View on GitHub (pinned to bb937076de)