Skip to content

Commit 8c1c70d

Browse files
authored
checker: fix x.$(field.name) not working outside of $if (#12802)
1 parent bf835d4 commit 8c1c70d

File tree

3 files changed

+57
-1
lines changed

3 files changed

+57
-1
lines changed

vlib/v/checker/checker.v

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -101,6 +101,7 @@ mut:
101101
prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then
102102
loop_label string // set when inside a labelled for loop
103103
timers &util.Timers = util.get_timers()
104+
comptime_fields_default_type ast.Type
104105
comptime_fields_type map[string]ast.Type
105106
fn_scope &ast.Scope = voidptr(0)
106107
main_fn_decl_node ast.FnDecl
@@ -2596,6 +2597,7 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
25962597
}
25972598
if node.kind == .fields {
25982599
c.comptime_fields_type[node.val_var] = node.typ
2600+
c.comptime_fields_default_type = node.typ
25992601
}
26002602
c.stmts(node.stmts)
26012603
}

vlib/v/checker/if.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
124124
node.branches[i].stmts = []
125125
}
126126
if comptime_field_name.len > 0 {
127-
c.comptime_fields_type.delete(comptime_field_name)
127+
c.comptime_fields_type[comptime_field_name] = c.comptime_fields_default_type
128128
}
129129
c.skip_flags = cur_skip_flags
130130
if c.fn_level == 0 && c.pref.output_cross_c && c.ct_cond_stack.len > 0 {
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
struct Abc {
2+
a byte
3+
b byte
4+
c int
5+
}
6+
7+
fn decode<T>() T {
8+
mut x := T{}
9+
$for field in T.fields {
10+
$if field.typ is byte {
11+
x.$(field.name) = 1
12+
} $else {
13+
x.$(field.name) = 3
14+
}
15+
if x.$(field.name) == 1 {
16+
x.$(field.name) = 5
17+
}
18+
}
19+
return x
20+
}
21+
22+
fn test_decode() {
23+
abc := decode<Abc>()
24+
assert abc.a == 5
25+
assert abc.b == 5
26+
assert abc.c == 3
27+
}
28+
29+
struct Abc2 {
30+
an_int int
31+
a_byte byte
32+
a_string string
33+
}
34+
35+
fn decode2<T>() T {
36+
mut x := T{}
37+
$for field in T.fields {
38+
$if field.typ is byte {
39+
x.$(field.name) = byte(-1)
40+
} $else $if field.typ is int {
41+
x.$(field.name) = int(-1)
42+
} $else {
43+
x.$(field.name) = 'hi'
44+
}
45+
}
46+
return x
47+
}
48+
49+
fn test_decode2() {
50+
abc := decode2<Abc2>()
51+
assert abc.an_int == -1
52+
assert abc.a_byte == 0xff
53+
assert abc.a_string == 'hi'
54+
}

0 commit comments

Comments
 (0)