checker, cgen: fix generic container init (fix #23910) (#23912)

This commit is contained in:
Felipe Pena 2025-03-12 09:04:13 -03:00 committed by GitHub
parent e32283fd1c
commit ad20a57139
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 39 additions and 4 deletions

View File

@ -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
}

View File

@ -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)}

View File

@ -0,0 +1,9 @@
fn decode[T]() {
_ := T{''}
_ := T{0}
_ := T{u8(1)}
}
fn main() {
decode[[]u8]()
}

View File

@ -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 {

View File

@ -0,0 +1,9 @@
fn decode[T]() {
a := T{123}
b := T{u8(123)}
assert a == b
}
fn test_main() {
decode[[]u8]()
}