{"record":{"id":"ae1e540185398313","repo":"slint-ui/slint","slug":"self-pointer-need-to-be-the-first","errorCode":null,"errorMessage":"Self pointer need to be the first","messagePattern":"Self pointer need to be the first","errorType":"exception","errorClass":"proc_macro::Error","httpStatus":null,"severity":"error","filePath":"helper_crates/vtable/macro/macro.rs","lineNumber":340,"sourceCode":"                    call_code = Some(quote!(vtable as _,));\n                    continue;\n                }\n\n                let (is_pin, self_ty) = match is_pin(&param.ty) {\n                    Some(t) => (true, t),\n                    None => (false, &param.ty),\n                };\n\n                // check for self\n                if let (true, mutability) = if match_generic_type(self_ty, \"VRef\", &vtable_name) {\n                    (true, None)\n                } else if match_generic_type(self_ty, \"VRefMut\", &vtable_name) {\n                    (true, Some(Default::default()))\n                } else {\n                    (false, None)\n                } {\n                    if !sig.inputs.is_empty() {\n                        return Error::new(param.span(), \"Self pointer need to be the first\")\n                            .to_compile_error()\n                            .into();\n                    }\n\n                    let const_or_mut = mutability.map_or_else(|| quote!(const), |x| quote!(#x));\n                    has_self = true;\n                    if !is_pin {\n                        sig.inputs.push(FnArg::Receiver(Receiver {\n                            attrs: param.attrs.clone(),\n                            mutability: None,\n                            self_token: Default::default(),\n                            kind: ReceiverKind::Reference(Default::default(), None, mutability),\n                        }));\n                        call_code =\n                            Some(quote!(#call_code <#self_ty>::from_raw(self.vtable, self.ptr),));\n                        self_call =\n                            Some(quote!(&#mutability (*(#arg_name.as_ptr() as *#const_or_mut T)),));\n                    } else {","sourceCodeStart":322,"sourceCodeEnd":358,"githubUrl":"https://github.com/slint-ui/slint/blob/bb937076de3f7919766c1f25e2e969367cf77e9a/helper_crates/vtable/macro/macro.rs#L322-L358","documentation":"When a vtable trait method takes self (VRef<Self>, VRefMut<Self> or &Self), that self-like pointer must be the first parameter so the macro can generate the correct dispatch thunks. If inputs precede the self parameter, the macro emits this compile error at the offending parameter.","triggerScenarios":"Writing e.g. `fn draw(ctx: &Ctx, self_: VRef<MyVTable>)` — any trait method where a VRef/VRefMut/&Self parameter is not first.","commonSituations":"Porting from trait syntax where `self` is implicit and adding explicit arguments before it; designing methods with a context/state parameter first out of habit from other frameworks.","solutions":["Reorder so the self-like parameter (VRef, VRefMut, &Self) comes first.","Pass extra context via the instance itself or via additional trailing parameters."],"exampleFix":"// before\nfn draw(ctx: &RenderContext, self_: VRef<MyVTable>);\n// after\nfn draw(self_: VRef<MyVTable>, ctx: &RenderContext);","handlingStrategy":"validation","validationCode":"// self-like parameter (VRef/VRefMut/&Self) must be first\nfn draw(self_: VRef<MyVTable>, ctx: &Ctx);","typeGuard":null,"tryCatchPattern":null,"preventionTips":["Adopt the convention: self parameter first, context/extra parameters after.","When adding parameters to an existing vtable method, insert them after the self parameter."],"tags":["proc-macro","argument-order","compile-time","rust"],"backgroundTag":"missing-required-argument","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"}