checker: fix x.$(field.name) not working outside of $if (#12802)

pull/12805/head
Leo Developer 2021-12-12 02:18:29 +01:00 committed by GitHub
parent bf835d47d8
commit 8c1c70db04
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 1 deletions

View File

@ -101,6 +101,7 @@ mut:
prevent_sum_type_unwrapping_once bool // needed for assign new values to sum type, stopping unwrapping then 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 loop_label string // set when inside a labelled for loop
timers &util.Timers = util.get_timers() timers &util.Timers = util.get_timers()
comptime_fields_default_type ast.Type
comptime_fields_type map[string]ast.Type comptime_fields_type map[string]ast.Type
fn_scope &ast.Scope = voidptr(0) fn_scope &ast.Scope = voidptr(0)
main_fn_decl_node ast.FnDecl main_fn_decl_node ast.FnDecl
@ -2596,6 +2597,7 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
} }
if node.kind == .fields { if node.kind == .fields {
c.comptime_fields_type[node.val_var] = node.typ c.comptime_fields_type[node.val_var] = node.typ
c.comptime_fields_default_type = node.typ
} }
c.stmts(node.stmts) c.stmts(node.stmts)
} }

View File

@ -124,7 +124,7 @@ pub fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type {
node.branches[i].stmts = [] node.branches[i].stmts = []
} }
if comptime_field_name.len > 0 { 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 c.skip_flags = cur_skip_flags
if c.fn_level == 0 && c.pref.output_cross_c && c.ct_cond_stack.len > 0 { if c.fn_level == 0 && c.pref.output_cross_c && c.ct_cond_stack.len > 0 {

View File

@ -0,0 +1,54 @@
struct Abc {
a byte
b byte
c int
}
fn decode<T>() 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<Abc>()
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>() 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<Abc2>()
assert abc.an_int == -1
assert abc.a_byte == 0xff
assert abc.a_string == 'hi'
}