From a59ebea5234c0c6c2597c9c1772eea8ec3ef74e6 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 3 Mar 2025 16:54:02 -0300 Subject: [PATCH] checker: add missing check for generic fntype type names (fix #23453) (#23850) --- vlib/v/checker/fn.v | 9 +++++++-- vlib/v/checker/tests/generic_fntype_err.out | 14 ++++++++++++++ vlib/v/checker/tests/generic_fntype_err.vv | 21 +++++++++++++++++++++ 3 files changed, 42 insertions(+), 2 deletions(-) create mode 100644 vlib/v/checker/tests/generic_fntype_err.out create mode 100644 vlib/v/checker/tests/generic_fntype_err.vv diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 1205fc208..061b14cd6 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -287,8 +287,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { param.typ = c.eval_array_fixed_sizes(mut size_expr, 0, arg_typ_sym.info.elem_type) mut v := node.scope.find_var(param.name) or { continue } v.typ = param.typ - } - if arg_typ_sym.info is ast.Struct { + } else if arg_typ_sym.info is ast.Struct { if !param.typ.is_ptr() && arg_typ_sym.info.is_heap { // set auto_heap to promote value parameter mut v := node.scope.find_var(param.name) or { continue } v.is_auto_heap = true @@ -317,6 +316,12 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.error('generic sumtype `${pure_sym_name}` in fn declaration must specify the generic type names, e.g. ${pure_sym_name}[T]', param.type_pos) } + } else if arg_typ_sym.info is ast.FnType { + if arg_typ_sym.info.func.generic_names.len > 0 && !param.typ.has_flag(.generic) { + pure_sym_name := arg_typ_sym.embed_name() + c.error('generic function `${pure_sym_name}` in fn declaration must specify the generic type names, e.g. ${pure_sym_name}[T]', + param.type_pos) + } } // Ensure each generic type of the parameter was declared in the function's definition if param.typ.has_flag(.generic) { diff --git a/vlib/v/checker/tests/generic_fntype_err.out b/vlib/v/checker/tests/generic_fntype_err.out new file mode 100644 index 000000000..2c59e7359 --- /dev/null +++ b/vlib/v/checker/tests/generic_fntype_err.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/generic_fntype_err.vv:19:15: error: cannot use `fn (int, int) int` as `fn (T, T) int` in argument 2 to `sort` + 17 | fn main() { + 18 | mut a := [123, 553, 223, 126, 883, 257] + 19 | x := sort(a, my_cmp) + | ~~~~~~ + 20 | println(x) + 21 | } +vlib/v/checker/tests/generic_fntype_err.vv:3:29: error: generic function `FnSort` in fn declaration must specify the generic type names, e.g. FnSort[T] + 1 | type FnSort[T] = fn (const_a T, const_b T) int + 2 | + 3 | fn sort[T](arr []T, sort_cb FnSort) []T { + | ~~~~~~ + 4 | return arr + 5 | } diff --git a/vlib/v/checker/tests/generic_fntype_err.vv b/vlib/v/checker/tests/generic_fntype_err.vv new file mode 100644 index 000000000..c40b06d7d --- /dev/null +++ b/vlib/v/checker/tests/generic_fntype_err.vv @@ -0,0 +1,21 @@ +type FnSort[T] = fn (const_a T, const_b T) int + +fn sort[T](arr []T, sort_cb FnSort) []T { + return arr +} + +fn my_cmp(a int, b int) int { + if a == b { + return 0 + } + if a < b { + return 1 + } + return -1 +} + +fn main() { + mut a := [123, 553, 223, 126, 883, 257] + x := sort(a, my_cmp) + println(x) +} -- 2.39.5