From 55cac8841a265c57b21b025b7673c3a58f4c09dd Mon Sep 17 00:00:00 2001 From: Swastik Baranwal Date: Mon, 13 Nov 2023 21:42:54 +0530 Subject: [PATCH] checker: disallow `$for i in struct.values` and `$for i in enum.fields` (#19845) --- vlib/v/checker/comptime.v | 8 ++++++++ vlib/v/checker/tests/for_comptime_enum_fields_err.out | 7 +++++++ vlib/v/checker/tests/for_comptime_enum_fields_err.vv | 8 ++++++++ vlib/v/checker/tests/for_comptime_struct_values_err.out | 7 +++++++ vlib/v/checker/tests/for_comptime_struct_values_err.vv | 7 +++++++ 5 files changed, 37 insertions(+) create mode 100644 vlib/v/checker/tests/for_comptime_enum_fields_err.out create mode 100644 vlib/v/checker/tests/for_comptime_enum_fields_err.vv create mode 100644 vlib/v/checker/tests/for_comptime_struct_values_err.out create mode 100644 vlib/v/checker/tests/for_comptime_struct_values_err.vv diff --git a/vlib/v/checker/comptime.v b/vlib/v/checker/comptime.v index fb1a98d1e..c3a55c43b 100644 --- a/vlib/v/checker/comptime.v +++ b/vlib/v/checker/comptime.v @@ -287,6 +287,10 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) { } c.comptime_for_field_var = '' c.inside_comptime_for_field = false + } else if c.table.generic_type_names(node.typ).len == 0 && sym.kind != .placeholder { + c.error('iterating over .fields is supported only for structs and interfaces, and ${sym.name} is neither', + node.typ_pos) + return } } else if node.kind == .values { if sym.kind == .enum_ { @@ -301,6 +305,10 @@ fn (mut c Checker) comptime_for(mut node ast.ComptimeFor) { c.comptime_fields_type[node.val_var] = node.typ c.stmts(mut node.stmts) } + } else { + c.error('iterating over .values is supported only for enums, and ${sym.name} is not an enum', + node.typ_pos) + return } } else { c.stmts(mut node.stmts) diff --git a/vlib/v/checker/tests/for_comptime_enum_fields_err.out b/vlib/v/checker/tests/for_comptime_enum_fields_err.out new file mode 100644 index 000000000..8c99aab27 --- /dev/null +++ b/vlib/v/checker/tests/for_comptime_enum_fields_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/for_comptime_enum_fields_err.vv:6:11: error: iterating over .fields is supported only for structs and interfaces, and Test is neither + 4 | } + 5 | + 6 | $for i in Test.fields { + | ~~~~ + 7 | println(i) + 8 | } diff --git a/vlib/v/checker/tests/for_comptime_enum_fields_err.vv b/vlib/v/checker/tests/for_comptime_enum_fields_err.vv new file mode 100644 index 000000000..07b90cf3b --- /dev/null +++ b/vlib/v/checker/tests/for_comptime_enum_fields_err.vv @@ -0,0 +1,8 @@ +enum Test { + one + two +} + +$for i in Test.fields { + println(i) +} diff --git a/vlib/v/checker/tests/for_comptime_struct_values_err.out b/vlib/v/checker/tests/for_comptime_struct_values_err.out new file mode 100644 index 000000000..8502ca049 --- /dev/null +++ b/vlib/v/checker/tests/for_comptime_struct_values_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/for_comptime_struct_values_err.vv:5:11: error: iterating over .values is supported only for enums, and Foo is not an enum + 3 | fn (_ Foo) hello() {} + 4 | + 5 | $for i in Foo.values { + | ~~~ + 6 | println(i) + 7 | } diff --git a/vlib/v/checker/tests/for_comptime_struct_values_err.vv b/vlib/v/checker/tests/for_comptime_struct_values_err.vv new file mode 100644 index 000000000..e41918b2c --- /dev/null +++ b/vlib/v/checker/tests/for_comptime_struct_values_err.vv @@ -0,0 +1,7 @@ +struct Foo{} + +fn (_ Foo) hello() {} + +$for i in Foo.values { + println(i) +} -- 2.39.5