diff --git a/cmd/tools/vast/vast.v b/cmd/tools/vast/vast.v index d39bb087baf608..f8e4db9828ee56 100644 --- a/cmd/tools/vast/vast.v +++ b/cmd/tools/vast/vast.v @@ -1645,6 +1645,7 @@ fn (t Tree) array_init(node ast.ArrayInit) &Node { obj.add('pre_cmnts', t.array_node_comment(node.pre_cmnts)) obj.add('elem_type_pos', t.pos(node.elem_type_pos)) obj.add_terse('is_fixed', t.bool_node(node.is_fixed)) + obj.add_terse('is_option', t.bool_node(node.is_option)) obj.add_terse('has_val', t.bool_node(node.has_val)) obj.add_terse('mod', t.string_node(node.mod)) obj.add_terse('len_expr', t.expr(node.len_expr)) diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 64cfead4abefea..b6b1bc0642c194 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -1546,12 +1546,13 @@ pub: ecmnts [][]Comment // optional iembed comments after each expr pre_cmnts []Comment is_fixed bool + is_option bool // true if it was declared as ?[2]Type or ?[]Type has_val bool // fixed size literal `[expr, expr]!` mod string has_len bool has_cap bool has_init bool - has_index bool // true if temp variable index is used + has_index bool // true if temp variable index is used pub mut: exprs []Expr // `[expr, expr]` or `[expr]Type{}` for fixed array len_expr Expr // len: expr diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index b94dd7a0232e30..37cced8ab54e97 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -285,6 +285,9 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { || c.array_fixed_has_unresolved_size(sym.info as ast.ArrayFixed) { mut size_expr := node.exprs[0] node.typ = c.eval_array_fixed_sizes(mut size_expr, 0, node.elem_type) + if node.is_option { + node.typ = node.typ.set_flag(.option) + } node.elem_type = (c.table.sym(node.typ).info as ast.ArrayFixed).elem_type } if node.has_init { diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 1e8498df2395f6..16a6b83941a978 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -131,7 +131,7 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st } elem_sym := g.table.final_sym(node.elem_type) is_struct := g.inside_array_fixed_struct && elem_sym.kind == .struct - if !is_struct { + if !is_struct && !node.is_option { g.write('{') } if node.has_val { @@ -212,6 +212,8 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st }) schan_expr := g.out.cut_to(before_chan_expr_pos) g.write_c99_elements_for_array(array_info.size, schan_expr) + } else if node.is_option { + g.gen_option_error(node.typ, ast.None{}) } else { std := g.type_default(node.elem_type) if g.can_use_c99_designators() && std == '0' { @@ -226,7 +228,7 @@ fn (mut g Gen) fixed_array_init(node ast.ArrayInit, array_type Type, var_name st } } } - if !is_struct { + if !is_struct && !node.is_option { g.write('}') } } diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index 87ab37dcaa0659..496b0770202273 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -192,6 +192,7 @@ fn (mut p Parser) array_init(is_option bool, alias_array_type ast.Type) ast.Arra has_index: has_index cap_expr: cap_expr init_expr: init_expr + is_option: is_option } } diff --git a/vlib/v/tests/array_fixed_none_init_test.v b/vlib/v/tests/array_fixed_none_init_test.v new file mode 100644 index 00000000000000..a30a77f876503b --- /dev/null +++ b/vlib/v/tests/array_fixed_none_init_test.v @@ -0,0 +1,13 @@ +fn test_none_init() { + a := ?[3]u8(none) + println(a) + assert a == none + + b := [3]u8{} + println(b) + assert b == none + + c := [3]u8{} + println(c) + assert c == none +}