From 21cc3c31fe8b64e5594fb5809db3b3b313fb6176 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 21 Jun 2025 13:57:18 -0300 Subject: [PATCH] cgen: fix sumtype option unwrapping (fix #24746) (#24770) --- vlib/v/gen/c/cgen.v | 8 +++- .../options/option_sumtype_unwrap_test.v | 40 +++++++++++++++++++ 2 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 vlib/v/tests/options/option_sumtype_unwrap_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index dc9ba569d..f8f3bff0e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5287,8 +5287,9 @@ fn (mut g Gen) ident(node ast.Ident) { obj_sym := g.table.sym(g.unwrap_generic(node.obj.typ)) if !prevent_sum_type_unwrapping_once { nested_unwrap := node.obj.smartcasts.len > 1 - if is_option && nested_unwrap && obj_sym.kind == .sum_type { - g.write('*(') + unwrap_sumtype := is_option && nested_unwrap && obj_sym.kind == .sum_type + if unwrap_sumtype { + g.write('(*(') } for i, typ in node.obj.smartcasts { is_option_unwrap := i == 0 && is_option @@ -5379,6 +5380,9 @@ fn (mut g Gen) ident(node ast.Ident) { && obj_sym.kind in [.sum_type, .interface] { g.write('${dot}_${cast_sym.cname}') } + if i != 0 && unwrap_sumtype { + g.write(')') + } } } if i == 0 && node.obj.ct_type_var != .smartcast && node.obj.is_unwrapped { diff --git a/vlib/v/tests/options/option_sumtype_unwrap_test.v b/vlib/v/tests/options/option_sumtype_unwrap_test.v new file mode 100644 index 000000000..076bdeb36 --- /dev/null +++ b/vlib/v/tests/options/option_sumtype_unwrap_test.v @@ -0,0 +1,40 @@ +type TxPayload = Can | u8 + +enum Tx { + empty + data + can +} + +fn (tx Tx) frame_bytes(payload ?TxPayload) ![]u8 { + match tx { + .empty { + return [u8(tx)] + } + .data { + if payload != none { + if payload is u8 { + return [u8(tx), payload] + } + } + return error('Invalid data') + } + .can { + if payload != none { + if payload is Can { + return [u8(tx), payload.net] + } + } + return error('Invalid can') + } + } +} + +struct Can { + net u8 +} + +fn test_main() { + assert Tx.empty.frame_bytes(none)! == [u8(0)] + assert Tx.data.frame_bytes(u8(123))! == [u8(1), 123] +} -- 2.39.5