From d9afebc277cc3b96c3df0b5b6538cfecffaaa712 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 5 May 2025 13:50:33 -0300 Subject: [PATCH] cgen: fix `if mut var != none {` for optional interface values (fix #24351) (#24410) --- vlib/v/gen/c/cgen.v | 13 +++++- .../v/tests/options/option_mut_if_none_test.v | 42 +++++++++++++++++++ 2 files changed, 53 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/options/option_mut_if_none_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 0638fb2b3c..e560659401 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5269,8 +5269,17 @@ fn (mut g Gen) ident(node ast.Ident) { is_option_unwrap := is_option && typ == node.obj.typ.clear_flag(.option) cast_sym := g.table.sym(g.unwrap_generic(typ)) if obj_sym.kind == .interface && cast_sym.kind == .interface { - ptr := '*'.repeat(node.obj.typ.nr_muls()) - g.write('I_${obj_sym.cname}_as_I_${cast_sym.cname}(${ptr}${node.name})') + if cast_sym.cname != obj_sym.cname { + ptr := '*'.repeat(node.obj.typ.nr_muls()) + g.write('I_${obj_sym.cname}_as_I_${cast_sym.cname}(${ptr}${node.name})') + } else { + ptr := if is_option { + '' + } else { + '*'.repeat(node.obj.typ.nr_muls()) + } + g.write('${ptr}${node.name}') + } } else { mut is_ptr := false if i == 0 { diff --git a/vlib/v/tests/options/option_mut_if_none_test.v b/vlib/v/tests/options/option_mut_if_none_test.v new file mode 100644 index 0000000000..175f92bd1e --- /dev/null +++ b/vlib/v/tests/options/option_mut_if_none_test.v @@ -0,0 +1,42 @@ +module main + +@[heap] +interface IGameObject { +mut: + name string + parent ?&IGameObject + next ?&IGameObject + child ?&IGameObject + last_child ?&IGameObject +} + +@[heap] +struct GameObject implements IGameObject { +mut: + name string + parent ?&IGameObject + next ?&IGameObject + child ?&IGameObject + last_child ?&IGameObject +} + +fn test_main() { + mut v1 := &GameObject{ + name: 'v1' + } + v1.next = &GameObject{ + name: 'v2' + } + + mut next := v1.next + for { + if mut next != none { + eprintln(next.name) + assert next.name == 'v2' + next = next.next + } else { + break + } + } + assert next == none +}