cgen: auto cast sum type in array init. fixes #6907
parent
fe0ded9a91
commit
34e124d5f7
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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(')')
|
||||
}
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue