diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 4c7c998ba7..f6666a0232 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -804,7 +804,7 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { unwrapped_typ = unaliased_type.clear_flags(.option, .result) } } - unwrapped_styp := g.typ(unwrapped_typ) + mut unwrapped_styp := g.typ(unwrapped_typ) if g.infix_left_var_name.len > 0 { g.indent-- g.writeln('}') @@ -814,6 +814,11 @@ fn (mut g Gen) call_expr(node ast.CallExpr) { g.write('\n ${cur_line}') } else if !g.inside_curry_call { if !g.inside_const_opt_or_res { + if g.assign_ct_type != 0 + && node.or_block.kind in [.propagate_option, .propagate_result] { + unwrapped_styp = g.typ(g.assign_ct_type.derive(node.return_type).clear_flags(.option, + .result)) + } g.write('\n ${cur_line} (*(${unwrapped_styp}*)${tmp_opt}.data)') } else { g.write('\n ${cur_line} ${tmp_opt}') diff --git a/vlib/v/tests/comptime_generic_ret_test.v b/vlib/v/tests/comptime_generic_ret_test.v new file mode 100644 index 0000000000..c547ac28f4 --- /dev/null +++ b/vlib/v/tests/comptime_generic_ret_test.v @@ -0,0 +1,48 @@ +struct Parent { +pub mut: + id int + name string + child Child + other Other +} + +struct Child { +pub mut: + id int + age int +} + +struct Other { +pub mut: + id int + name string +} + +interface IdInterface { +mut: + id int +} + +fn insert_ids[T](val T) !T { + mut clone := val + + $for field in T.fields { + $if field.typ is $struct { + clone.$(field.name) = insert_ids(val.$(field.name))! + } + } + $if T is IdInterface { + clone.id = 1 + } $else { + return error('${T.name} does not have an id field!') + } + return clone +} + +fn test_main() { + inserted := insert_ids(Parent{ + name: 'test' + })! + assert inserted.child.id == 1 + assert inserted.other.id == 1 +}