From ffa9faced0348650330154da522fd95beeae9a17 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Tue, 21 Apr 2026 05:21:37 +0300 Subject: [PATCH] cgen: fix optional val return in map got wrong value (fixes #26239) --- vlib/v/gen/c/index.v | 17 ++++++++++++++++- .../map_value_with_option_result_test.v | 12 ++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/vlib/v/gen/c/index.v b/vlib/v/gen/c/index.v index 720d64dc4..a8dbabe3d 100644 --- a/vlib/v/gen/c/index.v +++ b/vlib/v/gen/c/index.v @@ -802,6 +802,17 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) { } } if val_type.has_flag(.option) { + or_value_type := g.resolved_or_block_value_type(node.or_expr) + keep_option_result := node.is_option || (node.or_expr.kind == .block + && (or_value_type in [ast.none_type, ast.none_type_idx] + || or_value_type.has_flag(.option))) + plain_val_type := val_type.clear_option_and_result() + plain_val_sym := g.table.final_sym(plain_val_type) + plain_val_type_str := if plain_val_sym.kind == .function { + 'voidptr' + } else { + g.styp(plain_val_type) + } g.writeln('${val_type_str} ${tmp_opt} = {0};') g.writeln('if (${tmp_opt_ptr}) {') g.writeln('\t${tmp_opt} = *${tmp_opt_ptr};') @@ -814,7 +825,11 @@ fn (mut g Gen) index_of_map(node ast.IndexExpr, sym ast.TypeSymbol) { if is_gen_or_and_assign_rhs { g.set_current_pos_as_last_stmt_pos() } - g.write('\n${cur_line}${tmp_opt}') + if keep_option_result { + g.write('\n${cur_line}${tmp_opt}') + } else { + g.write('\n${cur_line}(*(${plain_val_type_str}*)${tmp_opt}.data)') + } } else { opt_val_type := g.styp(val_type.set_flag(.option)) g.writeln('${opt_val_type} ${tmp_opt} = {0};') diff --git a/vlib/v/tests/builtin_maps/map_value_with_option_result_test.v b/vlib/v/tests/builtin_maps/map_value_with_option_result_test.v index 040da247e..b6c163908 100644 --- a/vlib/v/tests/builtin_maps/map_value_with_option_result_test.v +++ b/vlib/v/tests/builtin_maps/map_value_with_option_result_test.v @@ -32,3 +32,15 @@ fn test_map_value_with_option_or_block() { assert value == none assert m['missing'] or { none } == none } + +fn test_map_value_with_option_or_block_value_fallback() { + mut m := map[string]?string{} + m['present'] = ?string('xyz') + m['none'] = ?string(none) + missing := m['missing'] or { 'abc' } + present := m['present'] or { 'abc' } + none_value := m['none'] or { 'abc' } + assert missing == 'abc' + assert present == 'xyz' + assert none_value == 'abc' +} -- 2.39.5