From f5b67802fd62fadcf26438291121aa289ea0b15f Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 16 Mar 2023 16:24:48 -0300 Subject: [PATCH] cgen: fix push operation on array of option (#17658) --- vlib/v/gen/c/auto_str_methods.v | 5 ++++- vlib/v/gen/c/infix.v | 23 ++++++++++++++--------- vlib/v/tests/option_push_array_opt_test.v | 15 +++++++++++++++ 3 files changed, 33 insertions(+), 10 deletions(-) create mode 100644 vlib/v/tests/option_push_array_opt_test.v diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index d1ec10153b..a478a18798 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -585,7 +585,10 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string // Rune are managed at this level as strings g.auto_str_funcs.writeln('\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_SLIT("\`"), ${c.si_s_code}, {.d_s = ${elem_str_fn_name}(it) }}, {_SLIT("\`"), 0, {.d_c = 0 }}}));\n') } else if sym.kind == .string { - if is_elem_ptr { + if typ.has_flag(.option) { + func := g.get_str_fn(typ) + g.auto_str_funcs.writeln('\t\tstring x = ${func}(it);\n') + } else if is_elem_ptr { g.auto_str_funcs.writeln('\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_SLIT("&\'"), ${c.si_s_code}, {.d_s = *it }}, {_SLIT("\'"), 0, {.d_c = 0 }}}));\n') } else { g.auto_str_funcs.writeln('\t\tstring x = str_intp(2, _MOV((StrIntpData[]){{_SLIT("\'"), ${c.si_s_code}, {.d_s = it }}, {_SLIT("\'"), 0, {.d_c = 0 }}}));\n') diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index cee2cf414b..5c30f95ea6 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -794,15 +794,20 @@ fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) { } else { g.write(', _MOV((${elem_type_str}[]){ ') } - // if g.autofree - needs_clone := !g.is_builtin_mod && array_info.elem_type.idx() == ast.string_type_idx - && array_info.elem_type.nr_muls() == 0 - if needs_clone { - g.write('string_clone(') - } - g.expr_with_cast(node.right, node.right_type, array_info.elem_type) - if needs_clone { - g.write(')') + if array_info.elem_type.has_flag(.option) { + g.expr_with_opt(node.right, node.right_type, array_info.elem_type) + } else { + // if g.autofree + needs_clone := !g.is_builtin_mod + && array_info.elem_type.idx() == ast.string_type_idx + && array_info.elem_type.nr_muls() == 0 + if needs_clone { + g.write('string_clone(') + } + g.expr_with_cast(node.right, node.right_type, array_info.elem_type) + if needs_clone { + g.write(')') + } } if elem_is_array_var { g.write(')') diff --git a/vlib/v/tests/option_push_array_opt_test.v b/vlib/v/tests/option_push_array_opt_test.v new file mode 100644 index 0000000000..3c98703fd2 --- /dev/null +++ b/vlib/v/tests/option_push_array_opt_test.v @@ -0,0 +1,15 @@ +fn test_dump_array_opt_push_string() { + mut vals := []?string{cap: 4} + vals << none + vals << 'a' + vals << 'b' + vals << 'c' + + t := dump(vals[0]) + assert t == none + + t2 := vals[0] + assert t2 == none + + assert vals.len == 4 +}