From d7d38926e2bdfc5c2e1871f64edcb8c1eea94b8a Mon Sep 17 00:00:00 2001 From: shove70 Date: Thu, 10 Aug 2023 14:06:54 +0800 Subject: [PATCH] cgen: fix spawn call fn struct field(fix #18862) --- vlib/v/gen/c/spawn_and_go.v | 14 +++++++++++--- .../c/testdata/spawn_call_fn_struct_field.out | 2 ++ .../c/testdata/spawn_call_fn_struct_field.vv | 18 ++++++++++++++++++ 3 files changed, 31 insertions(+), 3 deletions(-) create mode 100644 vlib/v/gen/c/testdata/spawn_call_fn_struct_field.out create mode 100644 vlib/v/gen/c/testdata/spawn_call_fn_struct_field.vv diff --git a/vlib/v/gen/c/spawn_and_go.v b/vlib/v/gen/c/spawn_and_go.v index b3d36ed50f..7c620e0f88 100644 --- a/vlib/v/gen/c/spawn_and_go.v +++ b/vlib/v/gen/c/spawn_and_go.v @@ -91,7 +91,8 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { } else { name } - if !(expr.is_method && g.table.sym(expr.receiver_type).kind == .interface_) { + if !(expr.is_method && (g.table.sym(expr.receiver_type).kind == .interface_ + || (g.table.sym(expr.receiver_type).kind == .struct_ && expr.is_field))) { g.writeln('${arg_tmp_var}${dot}fn = ${fn_name};') } if expr.is_method { @@ -250,7 +251,9 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { } } } - g.type_definitions.writeln('\t${fn_var};') + if fn_var != '' { + g.type_definitions.writeln('\t${fn_var};') + } if expr.is_method { styp := g.typ(expr.receiver_type) g.type_definitions.writeln('\t${styp} arg0;') @@ -298,11 +301,16 @@ fn (mut g Gen) spawn_and_go_expr(node ast.SpawnExpr, mode SpawnGoMode) { g.gowrappers.write_string('${idot}_typ]._method_${mname}(') g.gowrappers.write_string('arg->arg0') g.gowrappers.write_string('${idot}_object') + } else if typ_sym.kind == .struct_ && expr.is_field { + g.gowrappers.write_string('arg->arg0') + idot := if expr.left_type.is_ptr() { '->' } else { '.' } + mname := c_name(expr.name) + g.gowrappers.write_string('${idot}${mname}(') } else { g.gowrappers.write_string('arg->fn(') g.gowrappers.write_string('arg->arg0') } - if expr.args.len > 0 { + if expr.args.len > 0 && (typ_sym.kind != .struct_ || !expr.is_field) { g.gowrappers.write_string(', ') } } else { diff --git a/vlib/v/gen/c/testdata/spawn_call_fn_struct_field.out b/vlib/v/gen/c/testdata/spawn_call_fn_struct_field.out new file mode 100644 index 0000000000..317e9677c3 --- /dev/null +++ b/vlib/v/gen/c/testdata/spawn_call_fn_struct_field.out @@ -0,0 +1,2 @@ +hello +hello diff --git a/vlib/v/gen/c/testdata/spawn_call_fn_struct_field.vv b/vlib/v/gen/c/testdata/spawn_call_fn_struct_field.vv new file mode 100644 index 0000000000..a4604f5551 --- /dev/null +++ b/vlib/v/gen/c/testdata/spawn_call_fn_struct_field.vv @@ -0,0 +1,18 @@ +struct Foo { +mut: + func1 fn (int) = unsafe { nil } + func2 fn (int) = do +} + +fn do(a int) { + println('hello') +} + +mut foo := Foo{} + +foo.func1 = do +mut p := spawn foo.func1(1) +p.wait() + +p = spawn foo.func2(1) +p.wait()