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('keys', t.array_node_expr(node.keys)) | ||||
| 	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('pre_cmnts', t.array_node_comment(node.pre_cmnts)) | ||||
| 	obj.add('pos', t.pos(node.pos)) | ||||
|  |  | |||
|  | @ -1200,6 +1200,7 @@ pub: | |||
| pub mut: | ||||
| 	keys       []Expr | ||||
| 	vals       []Expr | ||||
| 	val_types  []Type | ||||
| 	typ        Type | ||||
| 	key_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() { | ||||
| 				val0_type = val0_type.deref() | ||||
| 			} | ||||
| 			node.val_types << val0_type | ||||
| 		} | ||||
| 		mut same_key_type := true | ||||
| 		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) | ||||
| 			c.expected_type = val0_type | ||||
| 			val_type := c.expr(val) | ||||
| 			node.val_types << val_type | ||||
| 			if !c.check_types(key_type, key0_type) || (i == 0 && key_type.is_number() | ||||
| 				&& key0_type.is_number() && key0_type != ast.mktyp(key_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) | ||||
| 	key_typ_str := g.typ(unwrap_key_typ) | ||||
| 	value_typ_str := g.typ(unwrap_val_typ) | ||||
| 	value_typ := g.table.sym(unwrap_val_typ) | ||||
| 	key_typ := g.table.final_sym(unwrap_key_typ) | ||||
| 	hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_typ) | ||||
| 	value_sym := g.table.sym(unwrap_val_typ) | ||||
| 	key_sym := g.table.final_sym(unwrap_key_typ) | ||||
| 	hash_fn, key_eq_fn, clone_fn, free_fn := g.map_fn_ptrs(key_sym) | ||||
| 	size := node.vals.len | ||||
| 	mut shared_styp := '' // only needed for shared &[]{...}
 | ||||
| 	mut styp := '' | ||||
|  | @ -4198,7 +4198,7 @@ fn (mut g Gen) map_init(node ast.MapInit) { | |||
| 		} | ||||
| 	} | ||||
| 	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]){') | ||||
| 		} 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]){') | ||||
|  | @ -4207,16 +4207,20 @@ fn (mut g Gen) map_init(node ast.MapInit) { | |||
| 			g.expr(expr) | ||||
| 			g.write(', ') | ||||
| 		} | ||||
| 		if value_typ.kind == .function { | ||||
| 		if value_sym.kind == .function { | ||||
| 			g.write('}), _MOV((voidptr[$size]){') | ||||
| 		} else { | ||||
| 			g.write('}), _MOV(($value_typ_str[$size]){') | ||||
| 		} | ||||
| 		for expr in node.vals { | ||||
| 		for i, expr in node.vals { | ||||
| 			if expr.is_auto_deref_var() { | ||||
| 				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('}))') | ||||
|  |  | |||
|  | @ -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