ast, checker, cgen: fix error for map sumtype value init (#13290)
parent
3fa9128716
commit
3bd528b218
|
@ -1589,6 +1589,7 @@ fn (t Tree) map_init(node ast.MapInit) &Node {
|
||||||
obj.add_terse('value_type', t.type_node(node.value_type))
|
obj.add_terse('value_type', t.type_node(node.value_type))
|
||||||
obj.add_terse('keys', t.array_node_expr(node.keys))
|
obj.add_terse('keys', t.array_node_expr(node.keys))
|
||||||
obj.add_terse('vals', t.array_node_expr(node.vals))
|
obj.add_terse('vals', t.array_node_expr(node.vals))
|
||||||
|
obj.add_terse('val_types', t.array_node_type(node.val_types))
|
||||||
obj.add('comments', t.two_dimension_comment(node.comments))
|
obj.add('comments', t.two_dimension_comment(node.comments))
|
||||||
obj.add('pre_cmnts', t.array_node_comment(node.pre_cmnts))
|
obj.add('pre_cmnts', t.array_node_comment(node.pre_cmnts))
|
||||||
obj.add('pos', t.pos(node.pos))
|
obj.add('pos', t.pos(node.pos))
|
||||||
|
|
|
@ -1200,6 +1200,7 @@ pub:
|
||||||
pub mut:
|
pub mut:
|
||||||
keys []Expr
|
keys []Expr
|
||||||
vals []Expr
|
vals []Expr
|
||||||
|
val_types []Type
|
||||||
typ Type
|
typ Type
|
||||||
key_type Type
|
key_type Type
|
||||||
value_type Type
|
value_type Type
|
||||||
|
|
|
@ -247,6 +247,7 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
|
||||||
if node.vals[0].is_auto_deref_var() {
|
if node.vals[0].is_auto_deref_var() {
|
||||||
val0_type = val0_type.deref()
|
val0_type = val0_type.deref()
|
||||||
}
|
}
|
||||||
|
node.val_types << val0_type
|
||||||
}
|
}
|
||||||
mut same_key_type := true
|
mut same_key_type := true
|
||||||
for i, key in node.keys {
|
for i, key in node.keys {
|
||||||
|
@ -258,6 +259,7 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
|
||||||
key_type := c.expr(key)
|
key_type := c.expr(key)
|
||||||
c.expected_type = val0_type
|
c.expected_type = val0_type
|
||||||
val_type := c.expr(val)
|
val_type := c.expr(val)
|
||||||
|
node.val_types << val_type
|
||||||
if !c.check_types(key_type, key0_type) || (i == 0 && key_type.is_number()
|
if !c.check_types(key_type, key0_type) || (i == 0 && key_type.is_number()
|
||||||
&& key0_type.is_number() && key0_type != ast.mktyp(key_type)) {
|
&& key0_type.is_number() && key0_type != ast.mktyp(key_type)) {
|
||||||
msg := c.expected_msg(key_type, key0_type)
|
msg := c.expected_msg(key_type, key0_type)
|
||||||
|
|
|
@ -4167,9 +4167,9 @@ fn (mut g Gen) map_init(node ast.MapInit) {
|
||||||
unwrap_val_typ := g.unwrap_generic(node.value_type)
|
unwrap_val_typ := g.unwrap_generic(node.value_type)
|
||||||
key_typ_str := g.typ(unwrap_key_typ)
|
key_typ_str := g.typ(unwrap_key_typ)
|
||||||
value_typ_str := g.typ(unwrap_val_typ)
|
value_typ_str := g.typ(unwrap_val_typ)
|
||||||
value_typ := g.table.sym(unwrap_val_typ)
|
value_sym := g.table.sym(unwrap_val_typ)
|
||||||
key_typ := g.table.final_sym(unwrap_key_typ)
|
key_sym := g.table.final_sym(unwrap_key_typ)
|
||||||
hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ)
|
hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_sym)
|
||||||
size := node.vals.len
|
size := node.vals.len
|
||||||
mut shared_styp := '' // only needed for shared &[]{...}
|
mut shared_styp := '' // only needed for shared &[]{...}
|
||||||
mut styp := ''
|
mut styp := ''
|
||||||
|
@ -4198,7 +4198,7 @@ fn (mut g Gen) map_init(node ast.MapInit) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if size > 0 {
|
if size > 0 {
|
||||||
if value_typ.kind == .function {
|
if value_sym.kind == .function {
|
||||||
g.write('new_map_init${noscan}($hash_fn, $key_eq_fn, $clone_fn, $free_fn, $size, sizeof($key_typ_str), sizeof(voidptr), _MOV(($key_typ_str[$size]){')
|
g.write('new_map_init${noscan}($hash_fn, $key_eq_fn, $clone_fn, $free_fn, $size, sizeof($key_typ_str), sizeof(voidptr), _MOV(($key_typ_str[$size]){')
|
||||||
} else {
|
} else {
|
||||||
g.write('new_map_init${noscan}($hash_fn, $key_eq_fn, $clone_fn, $free_fn, $size, sizeof($key_typ_str), sizeof($value_typ_str), _MOV(($key_typ_str[$size]){')
|
g.write('new_map_init${noscan}($hash_fn, $key_eq_fn, $clone_fn, $free_fn, $size, sizeof($key_typ_str), sizeof($value_typ_str), _MOV(($key_typ_str[$size]){')
|
||||||
|
@ -4207,16 +4207,20 @@ fn (mut g Gen) map_init(node ast.MapInit) {
|
||||||
g.expr(expr)
|
g.expr(expr)
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
if value_typ.kind == .function {
|
if value_sym.kind == .function {
|
||||||
g.write('}), _MOV((voidptr[$size]){')
|
g.write('}), _MOV((voidptr[$size]){')
|
||||||
} else {
|
} else {
|
||||||
g.write('}), _MOV(($value_typ_str[$size]){')
|
g.write('}), _MOV(($value_typ_str[$size]){')
|
||||||
}
|
}
|
||||||
for expr in node.vals {
|
for i, expr in node.vals {
|
||||||
if expr.is_auto_deref_var() {
|
if expr.is_auto_deref_var() {
|
||||||
g.write('*')
|
g.write('*')
|
||||||
}
|
}
|
||||||
g.expr(expr)
|
if value_sym.kind == .sum_type {
|
||||||
|
g.expr_with_cast(expr, node.val_types[i], unwrap_val_typ)
|
||||||
|
} else {
|
||||||
|
g.expr(expr)
|
||||||
|
}
|
||||||
g.write(', ')
|
g.write(', ')
|
||||||
}
|
}
|
||||||
g.write('}))')
|
g.write('}))')
|
||||||
|
|
|
@ -0,0 +1,18 @@
|
||||||
|
type Child = Tree | string
|
||||||
|
|
||||||
|
struct Tree {
|
||||||
|
name string
|
||||||
|
child map[string]Child
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_map_sumtype_value_init() {
|
||||||
|
tree := Tree{
|
||||||
|
name: 'foo'
|
||||||
|
child: {
|
||||||
|
'a': 'value'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
println(tree)
|
||||||
|
ret := tree.child['a'] or { Child('') }
|
||||||
|
assert ret == Child('value')
|
||||||
|
}
|
Loading…
Reference in New Issue