From a5e1f7430eaab15973e026bd2c7592a7b40bc3ab Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 01:40:05 +0300 Subject: [PATCH] checker: fix error for same function signature passed as argument (fixes #13965) --- vlib/v/checker/check_types.v | 13 ++++++++++++- .../same_function_signature_nested_fn_test.v | 19 +++++++++++++++++++ 2 files changed, 31 insertions(+), 1 deletion(-) create mode 100644 vlib/v/tests/fns/same_function_signature_nested_fn_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 24b47628a..acbcffea1 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -704,13 +704,24 @@ fn (mut c Checker) check_matching_function_symbols(got_type_sym &ast.TypeSymbol, || c.type_has_unresolved_generic_parts(exp_arg_typ) { continue } - if c.table.unaliased_type(got_arg_typ).idx() != c.table.unaliased_type(exp_arg_typ).idx() { + if !c.have_identical_fn_arg_type(got_arg_typ, exp_arg_typ) { return false } } return true } +fn (mut c Checker) have_identical_fn_arg_type(got ast.Type, expected ast.Type) bool { + got_unaliased := c.table.unaliased_type(got) + expected_unaliased := c.table.unaliased_type(expected) + got_final_sym := c.table.final_sym(got_unaliased) + expected_final_sym := c.table.final_sym(expected_unaliased) + if got_final_sym.kind == .function && expected_final_sym.kind == .function { + return c.check_matching_function_symbols(got_final_sym, expected_final_sym) + } + return got_unaliased.idx() == expected_unaliased.idx() +} + fn (mut c Checker) check_shift(mut node ast.InfixExpr, left_type_ ast.Type, right_type_ ast.Type) ast.Type { left_type := c.unwrap_generic(left_type_) right_type := c.unwrap_generic(right_type_) diff --git a/vlib/v/tests/fns/same_function_signature_nested_fn_test.v b/vlib/v/tests/fns/same_function_signature_nested_fn_test.v new file mode 100644 index 000000000..558682ca4 --- /dev/null +++ b/vlib/v/tests/fns/same_function_signature_nested_fn_test.v @@ -0,0 +1,19 @@ +type Transform = fn (string) string + +fn take_transform(cb fn (Transform) string) string { + return cb(to_upper) +} + +fn make_transform_callback() fn (fn (string) string) string { + return fn (cb fn (string) string) string { + return cb('x') + } +} + +fn to_upper(s string) string { + return s.to_upper() +} + +fn test_same_function_signature_nested_fn() { + assert take_transform(make_transform_callback()) == 'X' +} -- 2.39.5