From 010ace62e1bdcdf18a8f0a140d2d2234beff0927 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 4 May 2022 12:06:52 +0800 Subject: [PATCH] checker, cgen: check comptime selector that has no field name (#14282) --- vlib/v/checker/checker.v | 2 +- .../tests/comptime_selector_expr_type_err.out | 7 +++++++ .../tests/comptime_selector_expr_type_err.vv | 15 +++++++++++++++ vlib/v/gen/c/comptime.v | 7 ++++++- 4 files changed, 29 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/comptime_selector_expr_type_err.out create mode 100644 vlib/v/checker/tests/comptime_selector_expr_type_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index a56b23681b..102db9ef8a 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2661,7 +2661,7 @@ pub fn (mut c Checker) expr(node_ ast.Expr) ast.Type { return c.comptime_call(mut node) } ast.ComptimeSelector { - node.left_type = c.unwrap_generic(c.expr(node.left)) + node.left_type = c.expr(node.left) expr_type := c.unwrap_generic(c.expr(node.field_expr)) expr_sym := c.table.sym(expr_type) if expr_type != ast.string_type { diff --git a/vlib/v/checker/tests/comptime_selector_expr_type_err.out b/vlib/v/checker/tests/comptime_selector_expr_type_err.out new file mode 100644 index 0000000000..5505bb0146 --- /dev/null +++ b/vlib/v/checker/tests/comptime_selector_expr_type_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/comptime_selector_expr_type_err.vv:12:27: cgen error: `a` has no field named `value` + 10 | for i in a { + 11 | $for field in Row.fields { + 12 | println('field $i: ' + a.$(field.name).str() ) + | ^ + 13 | } + 14 | } diff --git a/vlib/v/checker/tests/comptime_selector_expr_type_err.vv b/vlib/v/checker/tests/comptime_selector_expr_type_err.vv new file mode 100644 index 0000000000..e4f6430924 --- /dev/null +++ b/vlib/v/checker/tests/comptime_selector_expr_type_err.vv @@ -0,0 +1,15 @@ +module main + +pub struct Row { +pub mut: + value string +} + +fn main() { + a := []Row{} + for i in a { + $for field in Row.fields { + println('field $i: ' + a.$(field.name).str() ) + } + } +} diff --git a/vlib/v/gen/c/comptime.v b/vlib/v/gen/c/comptime.v index 4245582cc9..c7e9d5db01 100644 --- a/vlib/v/gen/c/comptime.v +++ b/vlib/v/gen/c/comptime.v @@ -20,7 +20,12 @@ fn (mut g Gen) comptime_selector(node ast.ComptimeSelector) { if node.field_expr.expr is ast.Ident { if node.field_expr.expr.name == g.comptime_for_field_var && node.field_expr.field_name == 'name' { - g.write(c_name(g.comptime_for_field_value.name)) + field_name := g.comptime_for_field_value.name + left_sym := g.table.sym(g.unwrap_generic(node.left_type)) + _ := g.table.find_field_with_embeds(left_sym, field_name) or { + g.error('`$node.left` has no field named `$field_name`', node.left.pos()) + } + g.write(c_name(field_name)) return } }