cgen: auto cast sum type in array init. fixes #6907
parent
fe0ded9a91
commit
34e124d5f7
|
@ -825,6 +825,7 @@ pub:
|
||||||
has_cap bool
|
has_cap bool
|
||||||
has_default bool
|
has_default bool
|
||||||
pub mut:
|
pub mut:
|
||||||
|
expr_types []table.Type // [Dog, Cat] // also used for interface_types
|
||||||
is_interface bool // array of interfaces e.g. `[]Animal` `[Dog{}, Cat{}]`
|
is_interface bool // array of interfaces e.g. `[]Animal` `[Dog{}, Cat{}]`
|
||||||
interface_types []table.Type // [Dog, Cat]
|
interface_types []table.Type // [Dog, Cat]
|
||||||
interface_type table.Type // Animal
|
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 {
|
if array_init.exprs.len > 0 && array_init.elem_type == table.void_type {
|
||||||
mut expected_value_type := table.void_type
|
mut expected_value_type := table.void_type
|
||||||
mut expecting_interface_array := false
|
mut expecting_interface_array := false
|
||||||
cap := array_init.exprs.len
|
|
||||||
mut interface_types := []table.Type{cap: cap}
|
|
||||||
if c.expected_type != 0 {
|
if c.expected_type != 0 {
|
||||||
expected_value_type = c.table.value_type(c.expected_type)
|
expected_value_type = c.table.value_type(c.expected_type)
|
||||||
if c.table.get_type_symbol(expected_value_type).kind == .interface_ {
|
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 {
|
for i, expr in array_init.exprs {
|
||||||
typ := c.expr(expr)
|
typ := c.expr(expr)
|
||||||
|
array_init.expr_types << typ
|
||||||
|
// The first element's type
|
||||||
if expecting_interface_array {
|
if expecting_interface_array {
|
||||||
if i == 0 {
|
if i == 0 {
|
||||||
elem_type = expected_value_type
|
elem_type = expected_value_type
|
||||||
c.expected_type = elem_type
|
c.expected_type = elem_type
|
||||||
}
|
}
|
||||||
interface_types << typ
|
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
// The first element's type
|
// 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())
|
c.error('invalid array element: $err', expr.position())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if expecting_interface_array {
|
|
||||||
array_init.interface_types = interface_types
|
|
||||||
}
|
|
||||||
if array_init.is_fixed {
|
if array_init.is_fixed {
|
||||||
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len,
|
idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len,
|
||||||
1)
|
1)
|
||||||
|
|
|
@ -5844,11 +5844,11 @@ fn (mut g Gen) array_init(it ast.ArrayInit) {
|
||||||
}
|
}
|
||||||
for i, expr in it.exprs {
|
for i, expr in it.exprs {
|
||||||
if it.is_interface {
|
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)
|
// 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 {
|
if it.is_interface {
|
||||||
g.write(')')
|
g.write(')')
|
||||||
}
|
}
|
||||||
|
|
|
@ -194,3 +194,33 @@ fn test_array_init_direct_call() {
|
||||||
assert []int{len: 2, init: 0}.len == 2
|
assert []int{len: 2, init: 0}.len == 2
|
||||||
assert []int{len: 3, init: 1}.map(it*2) == [2,2,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