@@ -220,13 +220,37 @@ fn (mut g FlatGen) interface_method_stubs() {
220220fn (mut g FlatGen) gen_interface_dispatch (iface_name string , cn string , method string ) {
221221 sid := g.intern_string ('interface method ${cn }.${method } not implemented' )
222222 mname := '${iface_name }.${method }'
223- ret_type := g.tc.fn_ret_types[mname] or { types.Type (types.void_) }
223+ impls := g.iface_impls[iface_name] or { []string {} }
224+ // Interface-declared method signatures store named params unreliably (a named
225+ // param like `node &ast.Node` can be split into two type-only params). The
226+ // concrete implementer's method is a real fn_decl with a correctly parsed
227+ // signature, so derive the dispatch parameter types from the first implementer
228+ // that has the method. The receiver convention is resolved per implementer.
229+ mut sig_key := ''
230+ for concrete in impls {
231+ ck := '${concrete }.${method }'
232+ if ck in g.tc.fn_param_types {
233+ sig_key = ck
234+ break
235+ }
236+ }
237+ ret_type := g.tc.fn_ret_types[mname] or {
238+ if sig_key.len > 0 {
239+ g.tc.fn_ret_types[sig_key] or { types.Type (types.void_) }
240+ } else {
241+ types.Type (types.void_)
242+ }
243+ }
224244 ret_ct := g.optional_type_name (ret_type)
225- param_types := g.tc.fn_param_types[mname] or { []types.Type{} }
245+ mut sig_params := if sig_key.len > 0 {
246+ g.tc.fn_param_types[sig_key] or { []types.Type{} }
247+ } else {
248+ []types.Type{}
249+ }
226250 mut arg_names := []string {}
227251 g.write ('${ret_ct } ${cn }__${method }(${cn }* i' )
228- for pi := 1 ; pi < param_types .len; pi++ {
229- pt := param_types [pi]
252+ for pi := 1 ; pi < sig_params .len; pi++ {
253+ pt := sig_params [pi]
230254 pct := if pt is types.OptionType || pt is types.ResultType {
231255 g.optional_type_name (pt)
232256 } else {
@@ -237,7 +261,6 @@ fn (mut g FlatGen) gen_interface_dispatch(iface_name string, cn string, method s
237261 g.write (', ${pct } ${an }' )
238262 }
239263 g.writeln (') {' )
240- impls := g.iface_impls[iface_name] or { []string {} }
241264 if impls.len > 0 {
242265 g.writeln ('\t switch (i->_typ) {' )
243266 for concrete in impls {
0 commit comments