From 7faf1bf1d9aa0f5760163c2539521af51847b292 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Wed, 5 Mar 2025 09:13:52 -0300 Subject: [PATCH] cgen: fix casting primitive type to alias, where option alias is expected (fix #23859) (#23860) --- vlib/v/gen/c/assign.v | 14 ++++++-- .../options/option_cast_primitive_test.v | 35 +++++++++++++++++++ 2 files changed, 46 insertions(+), 3 deletions(-) create mode 100644 vlib/v/tests/options/option_cast_primitive_test.v diff --git a/vlib/v/gen/c/assign.v b/vlib/v/gen/c/assign.v index 602bd24df..d455ea24d 100644 --- a/vlib/v/gen/c/assign.v +++ b/vlib/v/gen/c/assign.v @@ -66,18 +66,26 @@ fn (mut g Gen) expr_opt_with_alias(expr ast.Expr, expr_typ ast.Type, ret_typ ast g.writeln('${ret_styp} ${ret_var} = {.state=2, .err=_const_none__, .data={EMPTY_STRUCT_INITIALIZATION}};') if expr !is ast.None { - g.write('_option_clone((${option_name}*)') - has_addr := expr !in [ast.Ident, ast.SelectorExpr] + is_option_expr := expr_typ.has_flag(.option) + if is_option_expr { + g.write('_option_clone((${option_name}*)') + } else { + g.write('_option_ok(&(${styp}[]){ ') + } + has_addr := is_option_expr && expr !in [ast.Ident, ast.SelectorExpr] if has_addr { expr_styp := g.styp(expr_typ).replace('*', '_ptr') g.write('ADDR(${expr_styp}, ') - } else { + } else if is_option_expr { g.write('&') } g.expr(expr) if has_addr { g.write(')') } + if !is_option_expr { + g.write(' }') + } g.writeln(', (${option_name}*)&${ret_var}, sizeof(${styp}));') } g.write(line) diff --git a/vlib/v/tests/options/option_cast_primitive_test.v b/vlib/v/tests/options/option_cast_primitive_test.v new file mode 100644 index 000000000..6a5301325 --- /dev/null +++ b/vlib/v/tests/options/option_cast_primitive_test.v @@ -0,0 +1,35 @@ +module main + +type Float = f32 + +struct Note { +mut: + seen string +} + +fn (mut n Note) bad_call(value ?Float) { + if val := value { + n.seen += ', ${val}' + } +} + +fn (mut n Note) good_call(value ?f32) { + if val := value { + n.seen += ', ${val}' + } +} + +fn test_main() { + mut good := Note{} + mut bad := Note{} + mut c := 0 + for { + good.good_call(f32(c)) + bad.bad_call(Float(c)) + c += 1 + if c >= 5 { + break + } + } + assert '${good.seen}' == '${bad.seen}' +} -- 2.39.5