Skip to content

Commit eb9bce3

Browse files
committed
v3: add missing ssa files and tests
1 parent 0c2fb3d commit eb9bce3

12 files changed

Lines changed: 2842 additions & 5 deletions

vlib/v3/gen/c/interface.v

Lines changed: 28 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -220,13 +220,37 @@ fn (mut g FlatGen) interface_method_stubs() {
220220
fn (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('\tswitch (i->_typ) {')
243266
for concrete in impls {

0 commit comments

Comments
 (0)