Skip to content

Commit e563c8f

Browse files
authored
cgen: fix infix expr ComptimeSelector type (fix #25659) (#25662)
1 parent 13764b3 commit e563c8f

File tree

2 files changed

+96
-2
lines changed

2 files changed

+96
-2
lines changed

vlib/v/gen/c/infix.v

Lines changed: 12 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1033,8 +1033,18 @@ fn (mut g Gen) infix_expr_arithmetic_op(node ast.InfixExpr) {
10331033
// infix_expr_left_shift_op generates code for the `<<` operator
10341034
// This can either be a value pushed into an array or a bit shift
10351035
fn (mut g Gen) infix_expr_left_shift_op(node ast.InfixExpr) {
1036-
left := g.unwrap(node.left_type)
1037-
right := g.unwrap(node.right_type)
1036+
left_type := if node.left is ast.ComptimeSelector {
1037+
g.type_resolver.get_type(node.left)
1038+
} else {
1039+
node.left_type
1040+
}
1041+
right_type := if node.right is ast.ComptimeSelector {
1042+
g.type_resolver.get_type(node.right)
1043+
} else {
1044+
node.right_type
1045+
}
1046+
left := g.unwrap(left_type)
1047+
right := g.unwrap(right_type)
10381048
if left.unaliased_sym.kind == .array {
10391049
// arr << val
10401050
tmp_var := g.new_tmp_var()
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
pub type Any = string | []Any | map[string]Any
2+
3+
pub fn decode_struct[T](value map[string]Any, mut t T) ! {
4+
$for f in T.fields {
5+
key := f.name
6+
vals := value[key] or { '' }
7+
if vals is string && vals != '' {
8+
$if f is string {
9+
t.$(f.name) = vals
10+
}
11+
} else if vals is map[string]Any {
12+
if f.is_struct {
13+
decode_struct(vals, mut t.$(f.name))!
14+
}
15+
} else if vals is []Any {
16+
$if f is $array {
17+
for val in vals {
18+
if val is map[string]Any {
19+
mut elem := array_element(t.$(f.name))
20+
$if elem is $struct {
21+
decode_struct(val, mut elem)!
22+
t.$(f.name) << elem
23+
}
24+
}
25+
}
26+
}
27+
}
28+
}
29+
}
30+
31+
fn array_element[T](a []T) T {
32+
return T{}
33+
}
34+
35+
struct Element {
36+
name string
37+
}
38+
39+
struct Set {
40+
name string
41+
elems []Element
42+
}
43+
44+
struct Tree {
45+
name string
46+
children []Tree
47+
}
48+
49+
const set_any = {
50+
'name': Any('1')
51+
'elems': Any([
52+
Any({
53+
'name': Any('2')
54+
}),
55+
{
56+
'name': Any('3')
57+
},
58+
])
59+
}
60+
const tree_any = {
61+
'name': Any('1')
62+
'children': Any([
63+
Any({
64+
'name': Any('2')
65+
}),
66+
{
67+
'name': Any('3')
68+
},
69+
])
70+
}
71+
72+
fn test_main() {
73+
mut set := Set{}
74+
decode_struct(set_any, mut set)!
75+
assert set.name == '1'
76+
assert set.elems[0].name == '2'
77+
assert set.elems[1].name == '3'
78+
79+
mut tree := Tree{}
80+
decode_struct(tree_any, mut tree)!
81+
assert tree.name == '1'
82+
assert tree.children[0].name == '2'
83+
assert tree.children[1].name == '3'
84+
}

0 commit comments

Comments
 (0)