From f60d2855850801b3dfc37d08c876068c2f7b3266 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Sat, 9 Nov 2024 08:46:59 -0300 Subject: [PATCH] checker: fix missing auto `from_string` type restriction (related to #22783) (#22803) --- vlib/v/checker/fn.v | 18 ++++++++++++++++++ .../tests/from_string_on_non_enum_err.out | 7 +++++++ .../tests/from_string_on_non_enum_err.vv | 14 ++++++++++++++ 3 files changed, 39 insertions(+) create mode 100644 vlib/v/checker/tests/from_string_on_non_enum_err.out create mode 100644 vlib/v/checker/tests/from_string_on_non_enum_err.vv diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 6699ae1fb..a3641fe0b 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1106,6 +1106,10 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast. if !c.check_type_and_visibility(full_enum_name, idx, .enum, node.pos) { return ast.void_type } + } else { + if !c.check_type_sym_kind(full_enum_name, idx, .enum, node.pos) { + return ast.void_type + } } } else if !enum_name.contains('.') { // find from another mods. @@ -2066,6 +2070,20 @@ fn (mut c Checker) cast_to_fixed_array_ret(typ ast.Type, sym ast.TypeSymbol) ast return typ } +// checks if a symbol kind is an expected kind +fn (mut c Checker) check_type_sym_kind(name string, type_idx int, expected_kind &ast.Kind, pos &token.Pos) bool { + mut sym := c.table.sym_by_idx(type_idx) + if sym.kind == .alias { + parent_type := (sym.info as ast.Alias).parent_type + sym = c.table.sym(parent_type) + } + if sym.kind != expected_kind { + c.error('expected ${expected_kind}, but `${name}` is ${sym.kind}', pos) + return false + } + return true +} + // checks if a type from another module is as expected and visible(`is_pub`) fn (mut c Checker) check_type_and_visibility(name string, type_idx int, expected_kind &ast.Kind, pos &token.Pos) bool { mut sym := c.table.sym_by_idx(type_idx) diff --git a/vlib/v/checker/tests/from_string_on_non_enum_err.out b/vlib/v/checker/tests/from_string_on_non_enum_err.out new file mode 100644 index 000000000..5c13c1316 --- /dev/null +++ b/vlib/v/checker/tests/from_string_on_non_enum_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/from_string_on_non_enum_err.vv:12:2: error: expected enum, but `Foo` is struct + 10 | + 11 | fn main() { + 12 | Foo.from_string('foo') + | ~~~~~~~~~~~~~~~~~~~~~~ + 13 | Bar.from_string('bar') + 14 | } diff --git a/vlib/v/checker/tests/from_string_on_non_enum_err.vv b/vlib/v/checker/tests/from_string_on_non_enum_err.vv new file mode 100644 index 000000000..8d55bebae --- /dev/null +++ b/vlib/v/checker/tests/from_string_on_non_enum_err.vv @@ -0,0 +1,14 @@ +struct Foo { + a int +} + +struct Bar { + b int +} + +fn Bar.from_string(a string) {} + +fn main() { + Foo.from_string('foo') + Bar.from_string('bar') +} -- 2.39.5