diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 7a3e43c423..9b213cf205 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -101,6 +101,7 @@ mut: prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then loop_label string // set when inside a labelled for loop timers &util.Timers = util.get_timers() + comptime_fields_default_type ast.Type comptime_fields_type map[string]ast.Type fn_scope &ast.Scope = voidptr(0) main_fn_decl_node ast.FnDecl @@ -2596,6 +2597,7 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) { } if node.kind == .fields { c.comptime_fields_type[node.val_var] = node.typ + c.comptime_fields_default_type = node.typ } c.stmts(node.stmts) } diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 75335d0c07..0f763ccb2e 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -124,7 +124,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { node.branches[i].stmts = [] } if comptime_field_name.len > 0 { - c.comptime_fields_type.delete(comptime_field_name) + c.comptime_fields_type[comptime_field_name] = c.comptime_fields_default_type } c.skip_flags = cur_skip_flags if c.fn_level == 0 && c.pref.output_cross_c && c.ct_cond_stack.len > 0 { diff --git a/vlib/v/tests/for_t_fields_with_comptime_if_test.v b/vlib/v/tests/for_t_fields_with_comptime_if_test.v new file mode 100644 index 0000000000..e2b4272295 --- /dev/null +++ b/vlib/v/tests/for_t_fields_with_comptime_if_test.v @@ -0,0 +1,54 @@ +struct Abc { + a byte + b byte + c int +} + +fn decode() T { + mut x := T{} + $for field in T.fields { + $if field.typ is byte { + x.$(field.name) = 1 + } $else { + x.$(field.name) = 3 + } + if x.$(field.name) == 1 { + x.$(field.name) = 5 + } + } + return x +} + +fn test_decode() { + abc := decode() + assert abc.a == 5 + assert abc.b == 5 + assert abc.c == 3 +} + +struct Abc2 { + an_int int + a_byte byte + a_string string +} + +fn decode2() T { + mut x := T{} + $for field in T.fields { + $if field.typ is byte { + x.$(field.name) = byte(-1) + } $else $if field.typ is int { + x.$(field.name) = int(-1) + } $else { + x.$(field.name) = 'hi' + } + } + return x +} + +fn test_decode2() { + abc := decode2() + assert abc.an_int == -1 + assert abc.a_byte == 0xff + assert abc.a_string == 'hi' +}