From 4bafc5042bfb52c7f65ec0f9309d1fa3aca2349d Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 3 Nov 2021 16:20:39 +0800 Subject: [PATCH] checker: check generic struct field fn args error (#12373) --- vlib/v/checker/checker.v | 4 ++- .../generics_struct_field_fn_args_err.out | 27 ++++++++++++++++ .../generics_struct_field_fn_args_err.vv | 31 +++++++++++++++++++ 3 files changed, 61 insertions(+), 1 deletion(-) create mode 100644 vlib/v/checker/tests/generics_struct_field_fn_args_err.out create mode 100644 vlib/v/checker/tests/generics_struct_field_fn_args_err.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 52f7f39775..9ad40d3325 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -2277,7 +2277,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { if field := c.table.find_field(left_type_sym, method_name) { field_type_sym := c.table.get_type_symbol(c.unwrap_generic(field.typ)) if field_type_sym.kind == .function { - // node.is_method = false + node.is_method = false node.is_field = true info := field_type_sym.info as ast.FnType node.return_type = info.func.return_type @@ -2288,6 +2288,8 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type { earg_types << targ } node.expected_arg_types = earg_types + c.check_expected_arg_count(mut node, info.func) or { return info.func.return_type } + node.is_method = true return info.func.return_type } } diff --git a/vlib/v/checker/tests/generics_struct_field_fn_args_err.out b/vlib/v/checker/tests/generics_struct_field_fn_args_err.out new file mode 100644 index 0000000000..0f13962941 --- /dev/null +++ b/vlib/v/checker/tests/generics_struct_field_fn_args_err.out @@ -0,0 +1,27 @@ +vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:21:20: error: expected 0 arguments, but got 1 + 19 | } + 20 | println(fun0.call()) + 21 | println(fun0.call(1234)) + | ~~~~ + 22 | println(fun0.call(1234, 5678)) + 23 | +vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:22:20: error: expected 0 arguments, but got 2 + 20 | println(fun0.call()) + 21 | println(fun0.call(1234)) + 22 | println(fun0.call(1234, 5678)) + | ~~~~~~~~~~ + 23 | + 24 | fun1 := Fun{ +vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:29:15: error: expected 1 arguments, but got 0 + 27 | + 28 | println(fun1.call(42)) + 29 | println(fun1.call()) + | ~~~~~~ + 30 | println(fun1.call(42, 43)) + 31 | } +vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:30:24: error: expected 1 arguments, but got 2 + 28 | println(fun1.call(42)) + 29 | println(fun1.call()) + 30 | println(fun1.call(42, 43)) + | ~~ + 31 | } diff --git a/vlib/v/checker/tests/generics_struct_field_fn_args_err.vv b/vlib/v/checker/tests/generics_struct_field_fn_args_err.vv new file mode 100644 index 0000000000..a75b68c7a2 --- /dev/null +++ b/vlib/v/checker/tests/generics_struct_field_fn_args_err.vv @@ -0,0 +1,31 @@ +fn get_int() int { + return 42 +} + +fn dub_int(i int) int { + return i * 2 +} + +struct Fun { +mut: + call F +} + +type FunZero = fn () int + +fn main() { + fun0 := Fun{ + call: get_int + } + println(fun0.call()) + println(fun0.call(1234)) + println(fun0.call(1234, 5678)) + + fun1 := Fun{ + call: dub_int + } + + println(fun1.call(42)) + println(fun1.call()) + println(fun1.call(42, 43)) +}