From 83e30a8104a3ef1dc966d6eeffb580ef5b90c6fc Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 10 Jun 2023 21:59:28 -0300 Subject: [PATCH] checker, cgen: fix comptime method and field name checking (#18402) --- vlib/v/checker/if.v | 24 +++++++++++++++++++ vlib/v/gen/c/comptime.v | 20 +++++++++++----- vlib/v/tests/comptime_field_name_check_test.v | 22 +++++++++++++++++ 3 files changed, 60 insertions(+), 6 deletions(-) create mode 100644 vlib/v/tests/comptime_field_name_check_test.v diff --git a/vlib/v/checker/if.v b/vlib/v/checker/if.v index 8c5163e581..ed30546222 100644 --- a/vlib/v/checker/if.v +++ b/vlib/v/checker/if.v @@ -220,6 +220,30 @@ fn (mut c Checker) if_expr(mut node ast.IfExpr) ast.Type { } } } + } else if branch.cond.op in [.eq, .ne] && left is ast.SelectorExpr + && right is ast.StringLiteral { + if left.expr.str() == c.comptime_for_field_var { + if left.field_name == 'name' { + is_comptime_type_is_expr = true + match branch.cond.op { + .eq { + skip_state = if c.comptime_for_field_value.name == right.val.str() { + ComptimeBranchSkipState.eval + } else { + ComptimeBranchSkipState.skip + } + } + .ne { + skip_state = if c.comptime_for_field_value.name == right.val.str() { + ComptimeBranchSkipState.skip + } else { + ComptimeBranchSkipState.eval + } + } + else {} + } + } + } } } } diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 0a96569c77..7a81bec0d4 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -555,22 +555,30 @@ fn (mut g Gen) comptime_if_cond(cond ast.Expr, pkg_exist bool) (bool, bool) { if selector.expr is ast.Ident && selector.field_name == 'name' { if g.comptime_for_method_var.len > 0 && (selector.expr as ast.Ident).name == g.comptime_for_method_var { - is_equal := g.comptime_for_method == cond.right.val - if is_equal { + is_true := if cond.op == .eq { + g.comptime_for_method == cond.right.val + } else { + g.comptime_for_method != cond.right.val + } + if is_true { g.write('1') } else { g.write('0') } - return is_equal, true + return is_true, true } else if g.comptime_for_field_var.len > 0 && (selector.expr as ast.Ident).name == g.comptime_for_field_var { - is_equal := g.comptime_for_field_value.name == cond.right.val - if is_equal { + is_true := if cond.op == .eq { + g.comptime_for_field_value.name == cond.right.val + } else { + g.comptime_for_field_value.name != cond.right.val + } + if is_true { g.write('1') } else { g.write('0') } - return is_equal, true + return is_true, true } } } else if cond.right is ast.IntegerLiteral { diff --git a/vlib/v/tests/comptime_field_name_check_test.v b/vlib/v/tests/comptime_field_name_check_test.v new file mode 100644 index 0000000000..cf22142ab4 --- /dev/null +++ b/vlib/v/tests/comptime_field_name_check_test.v @@ -0,0 +1,22 @@ +struct Struct { + a int + txt string + array []string +} + +fn get_string[T](s T) string { + $for field in T.fields { + $if field.name == 'txt' { + println(field.name) + return s.$(field.name) + } + } + return '' +} + +fn test_main() { + s := Struct{ + txt: 'hello' + } + assert get_string(s) == 'hello' +}