Skip to content

Commit ad20a57

Browse files
authored
checker, cgen: fix generic container init (fix #23910) (#23912)
1 parent e32283f commit ad20a57

5 files changed

Lines changed: 39 additions & 4 deletions

File tree

‎vlib/v/checker/containers.v‎

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,16 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type {
110110
if node.has_len {
111111
c.check_elements_ref_fields_initialized(unwrap_elem_type, node.pos)
112112
}
113+
// T{0} initialization when T is an array
114+
if !node.is_fixed && node.expr_types.len == 0 {
115+
for mut expr in node.exprs {
116+
typ := c.expr(mut expr)
117+
c.check_expected(typ, node.elem_type) or {
118+
c.error('invalid array element: ${err.msg()}', expr.pos())
119+
}
120+
node.expr_types << typ
121+
}
122+
}
113123
return node.typ
114124
}
115125

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
vlib/v/checker/tests/generic_array_init_err.vv:2:9: error: invalid array element: expected `u8`, not `string`
2+
1 | fn decode[T]() {
3+
2 | _ := T{''}
4+
| ~~
5+
3 | _ := T{0}
6+
4 | _ := T{u8(1)}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn decode[T]() {
2+
_ := T{''}
3+
_ := T{0}
4+
_ := T{u8(1)}
5+
}
6+
7+
fn main() {
8+
decode[[]u8]()
9+
}

‎vlib/v/gen/c/array.v‎

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,25 +47,26 @@ fn (mut g Gen) array_init(node ast.ArrayInit, var_name string) {
4747
}
4848
is_sumtype := elem_sym.kind == .sum_type
4949
for i, expr in node.exprs {
50-
if node.expr_types[i] == ast.string_type
50+
expr_type := if node.expr_types.len > i { node.expr_types[i] } else { node.elem_type }
51+
if expr_type == ast.string_type
5152
&& expr !in [ast.IndexExpr, ast.CallExpr, ast.StringLiteral, ast.StringInterLiteral, ast.InfixExpr] {
5253
if is_sumtype {
53-
g.expr_with_cast(expr, node.expr_types[i], node.elem_type)
54+
g.expr_with_cast(expr, expr_type, node.elem_type)
5455
} else {
5556
g.write('string_clone(')
5657
g.expr(expr)
5758
g.write(')')
5859
}
5960
} else {
6061
if node.elem_type.has_flag(.option) {
61-
g.expr_with_opt(expr, node.expr_types[i], node.elem_type)
62+
g.expr_with_opt(expr, expr_type, node.elem_type)
6263
} else if elem_type.unaliased_sym.kind == .array_fixed
6364
&& expr in [ast.Ident, ast.SelectorExpr] {
6465
info := elem_type.unaliased_sym.info as ast.ArrayFixed
6566
g.fixed_array_var_init(g.expr_string(expr), expr.is_auto_deref_var(),
6667
info.elem_type, info.size)
6768
} else {
68-
g.expr_with_cast(expr, node.expr_types[i], node.elem_type)
69+
g.expr_with_cast(expr, expr_type, node.elem_type)
6970
}
7071
}
7172
if i != len - 1 {
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn decode[T]() {
2+
a := T{123}
3+
b := T{u8(123)}
4+
assert a == b
5+
}
6+
7+
fn test_main() {
8+
decode[[]u8]()
9+
}

0 commit comments

Comments
 (0)