From 11acee1a5b174a8e4c09ddea32b73215acc151fb Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sun, 27 Apr 2025 22:35:12 -0300 Subject: [PATCH] cgen: fix codegen for nested selector option ptr (fix #24339) (#24345) --- vlib/v/gen/c/cgen.v | 11 +++-- .../options/option_nested_selector_test.v | 48 +++++++++++++++++++ 2 files changed, 54 insertions(+), 5 deletions(-) create mode 100644 vlib/v/tests/options/option_nested_selector_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index c1b299ed84..f6861dac29 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -4065,11 +4065,12 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { g.write('*') } g.write('${tmp_var} = ') - if is_ptr { + mut needs_addr := false + needs_deref := is_ptr && !is_option_unwrap + if needs_deref { g.write('*(') - } - needs_addr := is_option_unwrap && node.expr !in [ast.Ident, ast.PrefixExpr] - if is_option_unwrap { + } else if is_option_unwrap && !is_ptr { + needs_addr = node.expr !in [ast.Ident, ast.PrefixExpr] if !needs_addr { g.write('&') } else { @@ -4098,7 +4099,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { g.write('.') } g.write(field_name) - if is_ptr { + if needs_deref { g.write(')') } if needs_addr { diff --git a/vlib/v/tests/options/option_nested_selector_test.v b/vlib/v/tests/options/option_nested_selector_test.v new file mode 100644 index 0000000000..b3605c54f1 --- /dev/null +++ b/vlib/v/tests/options/option_nested_selector_test.v @@ -0,0 +1,48 @@ +module main + +@[heap] +interface IGameObject { +mut: + name string + parent ?&IGameObject + next ?&IGameObject + child ?&IGameObject + last_child ?&IGameObject + add_child(mut o IGameObject) +} + +@[heap] +struct GameObject implements IGameObject { +mut: + name string + parent ?&IGameObject + next ?&IGameObject + child ?&IGameObject + last_child ?&IGameObject +} + +fn (mut gameobject GameObject) add_child(mut o IGameObject) { + o.parent = gameobject + if gameobject.last_child != none { + gameobject.last_child.next = o + } else { + gameobject.child = o + } + gameobject.last_child = o +} + +fn test_main() { + mut v1 := &GameObject{ + name: 'v1' + } + mut v2 := &GameObject{ + name: 'v2' + } + mut v3 := &GameObject{ + name: 'v3' + } + v1.add_child(mut v2) + v1.add_child(mut v3) + + assert v1.child?.next?.name == 'v3' +}