diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 66be4430f1..ccaa55df57 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3937,6 +3937,25 @@ fn (mut g Gen) expr(node_ ast.Expr) { if g.is_option_auto_heap { g.write('(${g.base_type(node.right_type)}*)') } + mut tmp_var := '' + if node.op == .amp { + if node.right is ast.ParExpr && node.right.expr is ast.AsCast + && (node.right.expr as ast.AsCast).expr is ast.CallExpr { + str := g.go_before_last_stmt() + g.empty_line = true + typ := g.styp(((node.right as ast.ParExpr).expr as ast.AsCast).typ) + tmp_var = g.new_tmp_var() + g.writeln('${typ} ${tmp_var};') + g.stmts_with_tmp_var([ + ast.ExprStmt{ + pos: node.right.pos() + expr: node.right + }, + ], tmp_var) + g.set_current_pos_as_last_stmt_pos() + g.write(str) + } + } mut has_slice_call := false if !g.is_option_auto_heap && !(g.is_amp && node.right.is_auto_deref_var()) { has_slice_call = node.op == .amp && node.right is ast.IndexExpr @@ -3947,7 +3966,11 @@ fn (mut g Gen) expr(node_ ast.Expr) { g.write(node.op.str()) } } - g.expr(node.right) + if tmp_var == '' { + g.expr(node.right) + } else { + g.write(tmp_var) + } if has_slice_call { g.write(')') } diff --git a/vlib/v/tests/casts/cast_with_call_in_address_test.v b/vlib/v/tests/casts/cast_with_call_in_address_test.v new file mode 100644 index 0000000000..5cc85ba000 --- /dev/null +++ b/vlib/v/tests/casts/cast_with_call_in_address_test.v @@ -0,0 +1,37 @@ +@[heap] +struct Foo { +mut: + val int +} + +@[heap] +struct Bar { +mut: + val int +} + +interface FooBar { +mut: + val int +} + +fn test_main() { + mut fbs := []&FooBar{} + fbs << &Foo{1} + a := &(fbs[0] as Foo) + println(a) + b := &(fbs.last() as Foo) + println(b) + arr1 := [(fbs.last() as Foo)] + arr2 := [&(fbs.last() as Foo)] + arr3 := [&(get_foo_bar() as Foo)] + println(arr1) + println(arr2) + println(arr3) + println(&(fbs.last() as Foo)) + assert arr2[0] == arr3[0] +} + +fn get_foo_bar() FooBar { + return Foo{1} +}