diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 3169330a1a..a6f54779e8 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -825,6 +825,7 @@ pub: has_cap bool has_default bool pub mut: + expr_types []table.Type // [Dog, Cat] // also used for interface_types is_interface bool // array of interfaces e.g. `[]Animal` `[Dog{}, Cat{}]` interface_types []table.Type // [Dog, Cat] interface_type table.Type // Animal diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3becf8d40d..ebdfe464f9 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2353,8 +2353,6 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { if array_init.exprs.len > 0 && array_init.elem_type == table.void_type { mut expected_value_type := table.void_type mut expecting_interface_array := false - cap := array_init.exprs.len - mut interface_types := []table.Type{cap: cap} if c.expected_type != 0 { expected_value_type = c.table.value_type(c.expected_type) if c.table.get_type_symbol(expected_value_type).kind == .interface_ { @@ -2372,12 +2370,13 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { // } for i, expr in array_init.exprs { typ := c.expr(expr) + array_init.expr_types << typ + // The first element's type if expecting_interface_array { if i == 0 { elem_type = expected_value_type c.expected_type = elem_type } - interface_types << typ continue } // The first element's type @@ -2390,9 +2389,6 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { c.error('invalid array element: $err', expr.position()) } } - if expecting_interface_array { - array_init.interface_types = interface_types - } if array_init.is_fixed { idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len, 1) diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 0c4881e541..443952a9cd 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -5844,11 +5844,11 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { } for i, expr in it.exprs { if it.is_interface { - // sym := g.table.get_type_symbol(it.interface_types[i]) + // sym := g.table.get_type_symbol(it.expr_types[i]) // isym := g.table.get_type_symbol(it.interface_type) - g.interface_call(it.interface_types[i], it.interface_type) + g.interface_call(it.expr_types[i], it.interface_type) } - g.expr(expr) + g.expr_with_cast(expr, it.expr_types[i], it.elem_type) if it.is_interface { g.write(')') } diff --git a/vlib/v/tests/array_init_test.v b/vlib/v/tests/array_init_test.v index eebe939c87..70e03a2043 100644 --- a/vlib/v/tests/array_init_test.v +++ b/vlib/v/tests/array_init_test.v @@ -194,3 +194,33 @@ fn test_array_init_direct_call() { assert []int{len: 2, init: 0}.len == 2 assert []int{len: 3, init: 1}.map(it*2) == [2,2,2] } + +// test array init with sumtype +type Alphabet = Abc | Xyz +struct Abc { + val int +} +struct Xyz { + val int +} +fn test_array_init_with_sumtype () { + a := [Alphabet(Abc{1}), Xyz{2}] + a0 := a[0] + a1 := a[1] + match a0 { + Abc { + assert a0.val == 1 + } + else { + assert false + } + } + match a1 { + Xyz { + assert a1.val == 2 + } + else { + assert false + } + } +} \ No newline at end of file