Skip to content

Commit 0422147

Browse files
authored
cgen: fix go call interface method (fix #10520) (#10602)
1 parent 2bcc733 commit 0422147

File tree

2 files changed

+47
-2
lines changed

2 files changed

+47
-2
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5935,12 +5935,29 @@ fn (mut g Gen) go_expr(node ast.GoExpr) {
59355935
} else {
59365936
g.gowrappers.write_string('\t')
59375937
}
5938-
g.gowrappers.write_string('${name}(')
59395938
if expr.is_method {
5940-
g.gowrappers.write_string('arg->arg0')
5939+
unwrapped_rec_type := g.unwrap_generic(expr.receiver_type)
5940+
typ_sym := g.table.get_type_symbol(unwrapped_rec_type)
5941+
if typ_sym.kind == .interface_
5942+
&& (typ_sym.info as ast.Interface).defines_method(expr.name) {
5943+
rec_cc_type := g.cc_type(unwrapped_rec_type, false)
5944+
receiver_type_name := util.no_dots(rec_cc_type)
5945+
g.gowrappers.write_string('${c_name(receiver_type_name)}_name_table[')
5946+
g.gowrappers.write_string('arg->arg0')
5947+
dot := if expr.left_type.is_ptr() { '->' } else { '.' }
5948+
mname := c_name(expr.name)
5949+
g.gowrappers.write_string('${dot}_typ]._method_${mname}(')
5950+
g.gowrappers.write_string('arg->arg0')
5951+
g.gowrappers.write_string('${dot}_object')
5952+
} else {
5953+
g.gowrappers.write_string('${name}(')
5954+
g.gowrappers.write_string('arg->arg0')
5955+
}
59415956
if expr.args.len > 0 {
59425957
g.gowrappers.write_string(', ')
59435958
}
5959+
} else {
5960+
g.gowrappers.write_string('${name}(')
59445961
}
59455962
if expr.args.len > 0 {
59465963
mut has_cast := false
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
interface CanPerformTask {
2+
task()
3+
}
4+
5+
struct Task1 {}
6+
7+
fn (task1 Task1) task() {
8+
println('task1')
9+
}
10+
11+
struct Task2 {}
12+
13+
fn (task2 Task2) task() {
14+
println('task2')
15+
}
16+
17+
fn test_go_call_interface_method() {
18+
mut tasks := []CanPerformTask{}
19+
20+
tasks << Task1{}
21+
tasks << Task2{}
22+
23+
for task in tasks {
24+
go task.task()
25+
}
26+
27+
assert true
28+
}

0 commit comments

Comments
 (0)