diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index 19426734c4..c751f26a21 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -110,6 +110,16 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { if node.has_len { c.check_elements_ref_fields_initialized(unwrap_elem_type, node.pos) } + // T{0} initialization when T is an array + if !node.is_fixed && node.expr_types.len == 0 { + for mut expr in node.exprs { + typ := c.expr(mut expr) + c.check_expected(typ, node.elem_type) or { + c.error('invalid array element: ${err.msg()}', expr.pos()) + } + node.expr_types << typ + } + } return node.typ } diff --git a/vlib/v/checker/tests/generic_array_init_err.out b/vlib/v/checker/tests/generic_array_init_err.out new file mode 100644 index 0000000000..3d0e5eeea3 --- /dev/null +++ b/vlib/v/checker/tests/generic_array_init_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/generic_array_init_err.vv:2:9: error: invalid array element: expected `u8`, not `string` + 1 | fn decode[T]() { + 2 | _ := T{''} + | ~~ + 3 | _ := T{0} + 4 | _ := T{u8(1)} diff --git a/vlib/v/checker/tests/generic_array_init_err.vv b/vlib/v/checker/tests/generic_array_init_err.vv new file mode 100644 index 0000000000..109e588f4f --- /dev/null +++ b/vlib/v/checker/tests/generic_array_init_err.vv @@ -0,0 +1,9 @@ +fn decode[T]() { + _ := T{''} + _ := T{0} + _ := T{u8(1)} +} + +fn main() { + decode[[]u8]() +} diff --git a/vlib/v/gen/c/array.v b/vlib/v/gen/c/array.v index 35997fada2..b79c5334c7 100644 --- a/vlib/v/gen/c/array.v +++ b/vlib/v/gen/c/array.v @@ -47,10 +47,11 @@ fn (mut g Gen) array_init(node ast.ArrayInit, var_name string) { } is_sumtype := elem_sym.kind == .sum_type for i, expr in node.exprs { - if node.expr_types[i] == ast.string_type + expr_type := if node.expr_types.len > i { node.expr_types[i] } else { node.elem_type } + if expr_type == ast.string_type && expr !in [ast.IndexExpr, ast.CallExpr, ast.StringLiteral, ast.StringInterLiteral, ast.InfixExpr] { if is_sumtype { - g.expr_with_cast(expr, node.expr_types[i], node.elem_type) + g.expr_with_cast(expr, expr_type, node.elem_type) } else { g.write('string_clone(') g.expr(expr) @@ -58,14 +59,14 @@ fn (mut g Gen) array_init(node ast.ArrayInit, var_name string) { } } else { if node.elem_type.has_flag(.option) { - g.expr_with_opt(expr, node.expr_types[i], node.elem_type) + g.expr_with_opt(expr, expr_type, node.elem_type) } else if elem_type.unaliased_sym.kind == .array_fixed && expr in [ast.Ident, ast.SelectorExpr] { info := elem_type.unaliased_sym.info as ast.ArrayFixed g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(), info.elem_type, info.size) } else { - g.expr_with_cast(expr, node.expr_types[i], node.elem_type) + g.expr_with_cast(expr, expr_type, node.elem_type) } } if i != len - 1 { diff --git a/vlib/v/tests/generics/generic_array_init_test.v b/vlib/v/tests/generics/generic_array_init_test.v new file mode 100644 index 0000000000..0c88c2c033 --- /dev/null +++ b/vlib/v/tests/generics/generic_array_init_test.v @@ -0,0 +1,9 @@ +fn decode[T]() { + a := T{123} + b := T{u8(123)} + assert a == b +} + +fn test_main() { + decode[[]u8]() +}