diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 88f878a7c49e8a..3f0be328401833 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4208,6 +4208,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { mut sum_type_dot := '.' mut field_typ := ast.void_type mut is_option_unwrap := false + mut is_dereferenced := node.expr is ast.SelectorExpr && node.expr.expr_type.is_ptr() + && g.table.final_sym(node.expr.expr_type).kind in [.interface, .sum_type] if f := g.table.find_field_with_embeds(sym, node.field_name) { field_sym := g.table.sym(f.typ) field_typ = f.typ @@ -4374,8 +4376,8 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } alias_to_ptr := sym.info is ast.Alias && sym.info.parent_type.is_ptr() if field_is_opt - || ((g.unwrap_generic(node.expr_type).is_ptr() || sym.kind == .chan || alias_to_ptr) - && node.from_embed_types.len == 0) + || (((!is_dereferenced && g.unwrap_generic(node.expr_type).is_ptr()) + || sym.kind == .chan || alias_to_ptr) && node.from_embed_types.len == 0) || (node.expr.is_as_cast() && g.inside_smartcast) { g.write('->') } else { @@ -4389,7 +4391,12 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } g.write(field_name) if is_option_unwrap { - g.write('.data))') + if field_typ.is_ptr() { + g.write('->') + } else { + g.write('.') + } + g.write('data))') } if sum_type_deref_field != '' { g.write('${sum_type_dot}${sum_type_deref_field})') diff --git a/vlib/v/tests/options/option_selector_interface_ptr_test.v b/vlib/v/tests/options/option_selector_interface_ptr_test.v new file mode 100644 index 00000000000000..a2ab98fae96ece --- /dev/null +++ b/vlib/v/tests/options/option_selector_interface_ptr_test.v @@ -0,0 +1,35 @@ +module main + +interface IGameObject { +mut: + name string + parent ?&IGameObject + children []&IGameObject + add_child(mut o IGameObject) +} + +@[heap] +struct GameObject implements IGameObject { +mut: + name string + parent ?&IGameObject + children []&IGameObject +} + +fn (mut gameobject GameObject) add_child(mut o IGameObject) { + o.parent = gameobject + gameobject.children << o +} + +fn test_main() { + mut v1 := &GameObject{ + name: 'v1' + } + mut v2 := &GameObject{ + name: 'v2' + } + v1.add_child(mut v2) + if v1.children[0].parent != none { + assert '${v1.children[0].parent.name}' == 'v1' + } +}