From 752e4c2e4782e6feeaa9cff1f65414daab01cfdd Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 24 Jun 2023 14:54:49 -0300 Subject: [PATCH] cgen, checker: allow `a << none`, where `a` is `[]?&int` (#18539) --- vlib/v/checker/infix.v | 3 +++ vlib/v/gen/c/auto_str_methods.v | 16 ++++++++++++---- vlib/v/gen/c/infix.v | 2 +- vlib/v/tests/option_assign_none_test.v | 11 +++++++++++ 4 files changed, 27 insertions(+), 5 deletions(-) create mode 100644 vlib/v/tests/option_assign_none_test.v diff --git a/vlib/v/checker/infix.v b/vlib/v/checker/infix.v index d8e6dad130..a1e05ac112 100644 --- a/vlib/v/checker/infix.v +++ b/vlib/v/checker/infix.v @@ -522,6 +522,9 @@ fn (mut c Checker) infix_expr(mut node ast.InfixExpr) ast.Type { } else if c.check_types(unwrapped_right_type, c.unwrap_generic(left_type)) { return ast.void_type } + if left_value_type.has_flag(.option) && right_type == ast.none_type { + return ast.void_type + } c.error('cannot append `${right_sym.name}` to `${left_sym.name}`', right_pos) return ast.void_type } else { diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index 4c176d9dba..6eb43438a5 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -578,10 +578,14 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string deref, deref_label := deref_kind(str_method_expects_ptr, is_elem_ptr, typ) g.auto_str_funcs.writeln('\t\tstring x = _SLIT("nil");') - g.auto_str_funcs.writeln('\t\tif (it != 0) {') + if !typ.has_flag(.option) { + g.auto_str_funcs.writeln('\t\tif (it != 0) {') + } g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write_string(&sb, _SLIT("${deref_label}"));') g.auto_str_funcs.writeln('\t\t\tx = ${elem_str_fn_name}(${deref}it);') - g.auto_str_funcs.writeln('\t\t}') + if !typ.has_flag(.option) { + g.auto_str_funcs.writeln('\t\t}') + } } else { g.auto_str_funcs.writeln('\t\tstring x = indent_${elem_str_fn_name}(it, indent_count);') } @@ -610,10 +614,14 @@ fn (mut g Gen) gen_str_for_array(info ast.Array, styp string, str_fn_name string deref, deref_label := deref_kind(str_method_expects_ptr, is_elem_ptr, typ) if is_elem_ptr { g.auto_str_funcs.writeln('\t\tstring x = _SLIT("nil");') - g.auto_str_funcs.writeln('\t\tif (it != 0) {') + if !typ.has_flag(.option) { + g.auto_str_funcs.writeln('\t\tif (it != 0) {') + } g.auto_str_funcs.writeln('\t\t\tstrings__Builder_write_string(&sb, _SLIT("${deref_label}"));') g.auto_str_funcs.writeln('\t\t\tx = ${elem_str_fn_name}(${deref}it);') - g.auto_str_funcs.writeln('\t\t}') + if !typ.has_flag(.option) { + g.auto_str_funcs.writeln('\t\t}') + } } else { g.auto_str_funcs.writeln('\t\tstrings__Builder_write_string(&sb, _SLIT("${deref_label}"));') g.auto_str_funcs.writeln('\t\tstring x = ${elem_str_fn_name}(${deref}it);') diff --git a/vlib/v/gen/c/infix.v b/vlib/v/gen/c/infix.v index 7cc8a50f76..043b83b415 100644 --- a/vlib/v/gen/c/infix.v +++ b/vlib/v/gen/c/infix.v @@ -990,7 +990,7 @@ fn (mut g Gen) infix_expr_and_or_op(node ast.InfixExpr) { } fn (mut g Gen) gen_is_none_check(node ast.InfixExpr) { - if node.left in [ast.Ident, ast.SelectorExpr] { + if node.left in [ast.Ident, ast.SelectorExpr, ast.IndexExpr] { old_inside_opt_or_res := g.inside_opt_or_res g.inside_opt_or_res = true g.expr(node.left) diff --git a/vlib/v/tests/option_assign_none_test.v b/vlib/v/tests/option_assign_none_test.v new file mode 100644 index 0000000000..1ed324c7b9 --- /dev/null +++ b/vlib/v/tests/option_assign_none_test.v @@ -0,0 +1,11 @@ +fn test_main() { + mut a := []?&int{} + a << ?&int(none) + a << none + dump(a[0]) + dump(a[1]) + println(a) + + assert a[0] == none + assert a[1] == none +}