slint-ui/slint · error
Called a not-implemented method
Error message
Called a not-implemented method
What it means
The vtable crate's `vtable!` macro generates safe accessors for trait methods that call through an optional function pointer; when the vtable slot is None (method not implemented by the backing object), the generated code panics with 'Called a not-implemented method'. It means a caller invoked a trait method that the concrete object never registered in its vtable.
Solutions
- Fill in the missing method implementation in the vtable construction instead of None
- Regenerate/compile all vtable definitions after changing the trait so slots are populated
- For optional methods, check the slot (or an `has_*` helper) before calling instead of relying on the panic path
- Review unsafe code that builds vtables manually to ensure every required fn pointer is set
Example fix
// before
DropVTable { drop_in_place: Some(drop_in_place), ..Default::default() } // missing new method
// after
DropVTable { drop_in_place: Some(drop_in_place), new_method: Some(my_impl), ..Default::default() } Defensive patterns
Strategy: validation
Validate before calling
// before calling through the trait object, ensure the slot is implemented // check an availability helper or the vtable in debug assert!(vtable.some_method.is_some(), "some_method not implemented in vtable");
Try / catch
// use std::panic::catch_unwind around experimental dynamic dispatch paths let ok = std::panic::catch_unwind(std::panic::AssertUnwindSafe(|| obj.some_method()));
Prevention
- Never leave required vtable slots as None / Default
- Rebuild all dependents after changing a vtable trait
- Add compile-time or test-time assertions that all slots are populated
When it happens
Trigger: Accessing a trait object whose vtable left a method slot None and then calling that method — typically a partially implemented vtable or calling a method from a newer trait revision against an older/default vtable.
Common situations: Implementing a vtable struct with `None` (or Rust default) for a required method; adding a new method to a vtable trait without updating implementations; unsafe/direct construction of vtables in FFI code.
Related errors
- a setter belongs to a field
- an identifier
- attempt to multiply with overflow
- binding was of the wrong type
- Cannot get property
AI-assisted analysis of slint-ui/slint@bb937076de (2026-09-16).
Data as JSON: /api/errors/9594973703124ad5.
Report an issue: GitHub.
Appendix: source
Thrown at helper_crates/vtable/macro/macro.rs:499
default: None,
semi_token: Some(Default::default()),
}));
generated_to_fn_trait.push(ImplItemFn {
attrs: field.attrs.clone(),
vis: Visibility::Public(Default::default()),
modifiers: Default::default(),
sig: sig.clone(),
block: if has_self {
parse_quote!({
// Safety: this rely on the vtable being valid, and the ptr being a valid instance for this vtable
#[allow(unsafe_code)]
unsafe {
let vtable = self.vtable.as_ref();
if let #some(func) = vtable.#ident {
func (#call_code)
} else {
panic!("Called a not-implemented method")
}
}
})
} else {
// This should never happen: nobody should be able to access the Trait Object directly.
parse_quote!({ panic!("Calling Sized method on a Trait Object") })
},
});
if !has_self {
sig.inputs.insert(
0,
FnArg::Receiver(Receiver {
attrs: Default::default(),
mutability: None,
self_token: Default::default(),
kind: ReceiverKind::Reference(Default::default(), None, None),
}),View on GitHub (pinned to bb937076de)