From 4af4f2b5a5426285ff78b1771b940de52b20007c Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 28 Jun 2021 21:31:11 +0800 Subject: [PATCH] cgen: fix `go fn(mut x Interface){ println(x) }(x)` (#10585) --- vlib/v/gen/c/cgen.v | 32 ++++++++++++++++--- .../tests/go_wait_with_fn_of_interface_para.v | 17 ++++++++++ 2 files changed, 45 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/go_wait_with_fn_of_interface_para.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index bba6e989b1..a6b6cb74af 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5942,10 +5942,34 @@ fn (mut g Gen) go_expr(node ast.GoExpr) { g.gowrappers.write_string(', ') } } - for i in 0 .. expr.args.len { - g.gowrappers.write_string('arg->arg${i + 1}') - if i < expr.args.len - 1 { - g.gowrappers.write_string(', ') + if expr.args.len > 0 { + mut has_cast := false + for i in 0 .. expr.args.len { + if g.table.get_type_symbol(expr.expected_arg_types[i]).kind == .interface_ + && g.table.get_type_symbol(expr.args[i].typ).kind != .interface_ { + has_cast = true + break + } + } + if has_cast { + pos := g.out.len + g.call_args(expr) + mut call_args_str := g.out.after(pos) + g.out.go_back(call_args_str.len) + mut rep_group := []string{cap: 2 * expr.args.len} + for i in 0 .. expr.args.len { + rep_group << g.expr_string(expr.args[i].expr) + rep_group << 'arg->arg${i + 1}' + } + call_args_str = call_args_str.replace_each(rep_group) + g.gowrappers.write_string(call_args_str) + } else { + for i in 0 .. expr.args.len { + g.gowrappers.write_string('arg->arg${i + 1}') + if i != expr.args.len - 1 { + g.gowrappers.write_string(', ') + } + } } } g.gowrappers.writeln(');') diff --git a/vlib/v/tests/go_wait_with_fn_of_interface_para.v b/vlib/v/tests/go_wait_with_fn_of_interface_para.v new file mode 100644 index 0000000000..6cf6787e57 --- /dev/null +++ b/vlib/v/tests/go_wait_with_fn_of_interface_para.v @@ -0,0 +1,17 @@ +struct St1 { + val int = 5 +} + +interface In1 { + val int +} + +fn test_go_wait_with_fn_of_interface_type() { + mut var := &St1{} + (go fn1(mut var)).wait() +} + +fn fn1(mut v In1) { + println(v) + assert v.val == 5 +}