From 567a7d9d675fd7da5c45b27cbea052296314ea94 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Thu, 3 Apr 2025 10:54:40 -0300 Subject: [PATCH] checker: fix wrong type hint on predicate arg type mismatch (fix #24122) (#24123) --- vlib/v/checker/fn.v | 13 ++++++------ .../tests/wrong_predicate_type_err.out | 7 +++++++ .../checker/tests/wrong_predicate_type_err.vv | 21 +++++++++++++++++++ 3 files changed, 34 insertions(+), 7 deletions(-) create mode 100644 vlib/v/checker/tests/wrong_predicate_type_err.out create mode 100644 vlib/v/checker/tests/wrong_predicate_type_err.vv diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 81cb72c60..71cd6441b 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -2957,7 +2957,6 @@ fn (mut c Checker) check_predicate_param(is_map bool, elem_typ ast.Type, node as // Finish early so that it doesn't fail later return } - elem_sym := c.table.sym(elem_typ) arg_expr := node.args[0].expr match arg_expr { ast.AnonFn { @@ -2969,11 +2968,11 @@ fn (mut c Checker) check_predicate_param(is_map bool, elem_typ ast.Type, node as c.error('function needs exactly 1 argument', arg_expr.decl.pos) } else if is_map && (arg_expr.decl.return_type == ast.void_type || arg_expr.decl.params[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a ${elem_sym.name}) T {...}`', + c.error('type mismatch, should use `fn(a ${c.table.type_to_str(elem_typ)}) T {...}`', arg_expr.decl.pos) } else if !is_map && (arg_expr.decl.return_type != ast.bool_type || arg_expr.decl.params[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a ${elem_sym.name}) bool {...}`', + c.error('type mismatch, should use `fn(a ${c.table.type_to_str(elem_typ)}) bool {...}`', arg_expr.decl.pos) } } @@ -2991,11 +2990,11 @@ fn (mut c Checker) check_predicate_param(is_map bool, elem_typ ast.Type, node as c.error('function needs exactly 1 argument', node.pos) } else if is_map && (func.return_type == ast.void_type || func.params[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a ${elem_sym.name}) T {...}`', + c.error('type mismatch, should use `fn(a ${c.table.type_to_str(elem_typ)}) T {...}`', arg_expr.pos) } else if !is_map && (func.return_type != ast.bool_type || func.params[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a ${elem_sym.name}) bool {...}`', + c.error('type mismatch, should use `fn(a ${c.table.type_to_str(elem_typ)}) bool {...}`', arg_expr.pos) } } else if arg_expr.kind == .variable { @@ -3011,11 +3010,11 @@ fn (mut c Checker) check_predicate_param(is_map bool, elem_typ ast.Type, node as c.error('function needs exactly 1 argument', expr.decl.pos) } else if is_map && (expr.decl.return_type == ast.void_type || expr.decl.params[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a ${elem_sym.name}) T {...}`', + c.error('type mismatch, should use `fn(a ${c.table.type_to_str(elem_typ)}) T {...}`', expr.decl.pos) } else if !is_map && (expr.decl.return_type != ast.bool_type || expr.decl.params[0].typ != elem_typ) { - c.error('type mismatch, should use `fn(a ${elem_sym.name}) bool {...}`', + c.error('type mismatch, should use `fn(a ${c.table.type_to_str(elem_typ)}) bool {...}`', expr.decl.pos) } return diff --git a/vlib/v/checker/tests/wrong_predicate_type_err.out b/vlib/v/checker/tests/wrong_predicate_type_err.out new file mode 100644 index 000000000..f1f5fd9ab --- /dev/null +++ b/vlib/v/checker/tests/wrong_predicate_type_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/wrong_predicate_type_err.vv:18:13: error: type mismatch, should use `fn(a &Foo) bool {...}` + 16 | + 17 | fn main() { + 18 | t().filter(fn (a Foo) bool { + | ~~~~~~~~~~~~~~~~~ + 19 | return true + 20 | }) diff --git a/vlib/v/checker/tests/wrong_predicate_type_err.vv b/vlib/v/checker/tests/wrong_predicate_type_err.vv new file mode 100644 index 000000000..b14f70393 --- /dev/null +++ b/vlib/v/checker/tests/wrong_predicate_type_err.vv @@ -0,0 +1,21 @@ +@[heap] +struct Foo { + field int +} + +fn t() []&Foo { + mut a := []&Foo{} + a << &Foo{ + field: 1 + } + a << &Foo{ + field: 2 + } + return a +} + +fn main() { + t().filter(fn (a Foo) bool { + return true + }) +} -- 2.39.5