Skip to content

Commit c3ee26f

Browse files
authored
checker,cgen: fix dump when using comptime variable val.${field.name} (#16671)
1 parent f762d46 commit c3ee26f

File tree

5 files changed

+64
-8
lines changed

5 files changed

+64
-8
lines changed

vlib/v/checker/comptime.v

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -183,6 +183,10 @@ fn (mut c Checker) comptime_for(node ast.ComptimeFor) {
183183
c.comptime_fields_type[node.val_var] = node.typ
184184
c.comptime_fields_default_type = field.typ
185185
c.stmts(node.stmts)
186+
187+
unwrapped_expr_type := c.unwrap_generic(field.typ)
188+
tsym := c.table.sym(unwrapped_expr_type)
189+
c.table.dumps[int(unwrapped_expr_type.clear_flag(.optional).clear_flag(.result))] = tsym.cname
186190
}
187191
c.inside_comptime_for_field = false
188192
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$field.name: c
2+
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$field.name: d
3+
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$field.name: 1
4+
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$field.name: 0
5+
[vlib/v/checker/tests/comptime_dump_fields_var_test.vv:13] val.$field.name: _VAnonStruct1{
6+
i: 100
7+
}
8+
ok
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
struct Foo {
2+
a string
3+
b ?string
4+
c int
5+
d ?int
6+
e struct {
7+
i ?int
8+
}
9+
}
10+
11+
fn run[T](val T) {
12+
$for field in T.fields {
13+
dump(val.$(field.name))
14+
}
15+
println('ok')
16+
}
17+
18+
fn test_main() {
19+
foo := Foo{'c', 'd', 1, 0, struct {100}}
20+
run(foo)
21+
}

vlib/v/gen/c/comptime.v

Lines changed: 10 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,15 @@ import v.ast
88
import v.util
99
import v.pref
1010

11+
fn (mut g Gen) get_comptime_selector_var_type(node ast.ComptimeSelector) (ast.StructField, string) {
12+
field_name := g.comptime_for_field_value.name
13+
left_sym := g.table.sym(g.unwrap_generic(node.left_type))
14+
field := g.table.find_field_with_embeds(left_sym, field_name) or {
15+
g.error('`${node.left}` has no field named `${field_name}`', node.left.pos())
16+
}
17+
return field, field_name
18+
}
19+
1120
fn (mut g Gen) comptime_selector(node ast.ComptimeSelector) {
1221
g.expr(node.left)
1322
if node.left_type.is_ptr() {
@@ -20,11 +29,7 @@ fn (mut g Gen) comptime_selector(node ast.ComptimeSelector) {
2029
if node.field_expr.expr is ast.Ident {
2130
if node.field_expr.expr.name == g.comptime_for_field_var
2231
&& node.field_expr.field_name == 'name' {
23-
field_name := g.comptime_for_field_value.name
24-
left_sym := g.table.sym(g.unwrap_generic(node.left_type))
25-
_ := g.table.find_field_with_embeds(left_sym, field_name) or {
26-
g.error('`${node.left}` has no field named `${field_name}`', node.left.pos())
27-
}
32+
_, field_name := g.get_comptime_selector_var_type(node)
2833
g.write(c_name(field_name))
2934
return
3035
}

vlib/v/gen/c/dumpexpr.v

Lines changed: 21 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,17 +13,35 @@ fn (mut g Gen) dump_expr(node ast.DumpExpr) {
1313
return
1414
}
1515
mut name := node.cname
16+
mut expr_type := node.expr_type
17+
18+
// var.${field.name}
19+
if node.expr is ast.ComptimeSelector {
20+
selector := node.expr as ast.ComptimeSelector
21+
if selector.field_expr is ast.SelectorExpr {
22+
selector_expr := selector.field_expr as ast.SelectorExpr
23+
if selector_expr.expr is ast.Ident {
24+
ident_expr := selector_expr.expr
25+
if ident_expr.name == g.comptime_for_field_var && selector_expr.field_name == 'name' {
26+
field, _ := g.get_comptime_selector_var_type(selector)
27+
name = g.typ(g.unwrap_generic(field.typ.clear_flag(.shared_f).clear_flag(.optional).clear_flag(.result)))
28+
expr_type = field.typ
29+
}
30+
}
31+
}
32+
}
33+
1634
if g.table.sym(node.expr_type).language == .c {
1735
name = name[3..]
1836
}
1937
dump_fn_name := '_v_dump_expr_${name}' +
20-
(if node.expr_type.is_ptr() { '_ptr'.repeat(node.expr_type.nr_muls()) } else { '' })
38+
(if expr_type.is_ptr() { '_ptr'.repeat(expr_type.nr_muls()) } else { '' })
2139
g.write(' ${dump_fn_name}(${ctoslit(fpath)}, ${line}, ${sexpr}, ')
22-
if node.expr_type.has_flag(.shared_f) {
40+
if expr_type.has_flag(.shared_f) {
2341
g.write('&')
2442
g.expr(node.expr)
2543
g.write('->val')
26-
} else if node.expr_type.has_flag(.optional) || node.expr_type.has_flag(.result) {
44+
} else if expr_type.has_flag(.optional) || expr_type.has_flag(.result) {
2745
old_inside_opt_or_res := g.inside_opt_or_res
2846
g.inside_opt_or_res = true
2947
g.write('(*(${name}*)')

0 commit comments

Comments
 (0)