ast, checker, cgen: fix error for map sumtype value init (#13290)

pull/13294/head
yuyi 2022-01-27 15:44:34 +08:00 committed by GitHub
parent 3fa9128716
commit 3bd528b218
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 33 additions and 7 deletions

View File

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

View File

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

View File

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

View File

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

View File

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