Skip to content

Commit 3bd528b

Browse files
authored
ast, checker, cgen: fix error for map sumtype value init (#13290)
1 parent 3fa9128 commit 3bd528b

File tree

5 files changed

+33
-7
lines changed

5 files changed

+33
-7
lines changed

cmd/tools/vast/vast.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1589,6 +1589,7 @@ fn (t Tree) map_init(node ast.MapInit) &Node {
15891589
obj.add_terse('value_type', t.type_node(node.value_type))
15901590
obj.add_terse('keys', t.array_node_expr(node.keys))
15911591
obj.add_terse('vals', t.array_node_expr(node.vals))
1592+
obj.add_terse('val_types', t.array_node_type(node.val_types))
15921593
obj.add('comments', t.two_dimension_comment(node.comments))
15931594
obj.add('pre_cmnts', t.array_node_comment(node.pre_cmnts))
15941595
obj.add('pos', t.pos(node.pos))

vlib/v/ast/ast.v

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1200,6 +1200,7 @@ pub:
12001200
pub mut:
12011201
keys []Expr
12021202
vals []Expr
1203+
val_types []Type
12031204
typ Type
12041205
key_type Type
12051206
value_type Type

vlib/v/checker/containers.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,7 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
247247
if node.vals[0].is_auto_deref_var() {
248248
val0_type = val0_type.deref()
249249
}
250+
node.val_types << val0_type
250251
}
251252
mut same_key_type := true
252253
for i, key in node.keys {
@@ -258,6 +259,7 @@ pub fn (mut c Checker) map_init(mut node ast.MapInit) ast.Type {
258259
key_type := c.expr(key)
259260
c.expected_type = val0_type
260261
val_type := c.expr(val)
262+
node.val_types << val_type
261263
if !c.check_types(key_type, key0_type) || (i == 0 && key_type.is_number()
262264
&& key0_type.is_number() && key0_type != ast.mktyp(key_type)) {
263265
msg := c.expected_msg(key_type, key0_type)

vlib/v/gen/c/cgen.v

Lines changed: 11 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -4167,9 +4167,9 @@ fn (mut g Gen) map_init(node ast.MapInit) {
41674167
unwrap_val_typ := g.unwrap_generic(node.value_type)
41684168
key_typ_str := g.typ(unwrap_key_typ)
41694169
value_typ_str := g.typ(unwrap_val_typ)
4170-
value_typ := g.table.sym(unwrap_val_typ)
4171-
key_typ := g.table.final_sym(unwrap_key_typ)
4172-
hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ)
4170+
value_sym := g.table.sym(unwrap_val_typ)
4171+
key_sym := g.table.final_sym(unwrap_key_typ)
4172+
hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_sym)
41734173
size := node.vals.len
41744174
mut shared_styp := '' // only needed for shared &[]{...}
41754175
mut styp := ''
@@ -4198,7 +4198,7 @@ fn (mut g Gen) map_init(node ast.MapInit) {
41984198
}
41994199
}
42004200
if size > 0 {
4201-
if value_typ.kind == .function {
4201+
if value_sym.kind == .function {
42024202
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]){')
42034203
} else {
42044204
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) {
42074207
g.expr(expr)
42084208
g.write(', ')
42094209
}
4210-
if value_typ.kind == .function {
4210+
if value_sym.kind == .function {
42114211
g.write('}), _MOV((voidptr[$size]){')
42124212
} else {
42134213
g.write('}), _MOV(($value_typ_str[$size]){')
42144214
}
4215-
for expr in node.vals {
4215+
for i, expr in node.vals {
42164216
if expr.is_auto_deref_var() {
42174217
g.write('*')
42184218
}
4219-
g.expr(expr)
4219+
if value_sym.kind == .sum_type {
4220+
g.expr_with_cast(expr, node.val_types[i], unwrap_val_typ)
4221+
} else {
4222+
g.expr(expr)
4223+
}
42204224
g.write(', ')
42214225
}
42224226
g.write('}))')
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
type Child = Tree | string
2+
3+
struct Tree {
4+
name string
5+
child map[string]Child
6+
}
7+
8+
fn test_map_sumtype_value_init() {
9+
tree := Tree{
10+
name: 'foo'
11+
child: {
12+
'a': 'value'
13+
}
14+
}
15+
println(tree)
16+
ret := tree.child['a'] or { Child('') }
17+
assert ret == Child('value')
18+
}

0 commit comments

Comments
 (0)