From 73e28ec523163f2335a32583a07ec421d97e7f9b Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 6 Oct 2022 22:25:02 +0800 Subject: [PATCH] checker: fix infering fn type using reference argument (#15978) --- vlib/v/checker/check_types.v | 18 ++++++++++++++++++ ...neric_fn_infer_fn_type_using_ref_arg_test.v | 12 ++++++++++++ 2 files changed, 30 insertions(+) create mode 100644 vlib/v/tests/generic_fn_infer_fn_type_using_ref_arg_test.v diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index bc28a80d6e..b828c56b90 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -714,6 +714,9 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr } else { if param_elem_sym.name == gt_name { typ = arg_elem_info.elem_type + if param_elem_info.elem_type.nr_muls() > 0 && typ.nr_muls() > 0 { + typ = typ.set_nr_muls(0) + } } break } @@ -734,6 +737,9 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr } else { if param_elem_sym.name == gt_name { typ = arg_elem_info.elem_type + if param_elem_info.elem_type.nr_muls() > 0 && typ.nr_muls() > 0 { + typ = typ.set_nr_muls(0) + } } break } @@ -744,10 +750,16 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr if param_map_info.key_type.has_flag(.generic) && c.table.sym(param_map_info.key_type).name == gt_name { typ = arg_map_info.key_type + if param_map_info.key_type.nr_muls() > 0 && typ.nr_muls() > 0 { + typ = typ.set_nr_muls(0) + } } if param_map_info.value_type.has_flag(.generic) && c.table.sym(param_map_info.value_type).name == gt_name { typ = arg_map_info.value_type + if param_map_info.value_type.nr_muls() > 0 && typ.nr_muls() > 0 { + typ = typ.set_nr_muls(0) + } } } else if arg_sym.kind == .function && param_type_sym.kind == .function { arg_type_func := (arg_sym.info as ast.FnType).func @@ -757,11 +769,17 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr if fn_param.typ.has_flag(.generic) && c.table.sym(fn_param.typ).name == gt_name { typ = arg_type_func.params[n].typ + if fn_param.typ.nr_muls() > 0 && typ.nr_muls() > 0 { + typ = typ.set_nr_muls(0) + } } } if param_type_func.return_type.has_flag(.generic) && c.table.sym(param_type_func.return_type).name == gt_name { typ = arg_type_func.return_type + if param_type_func.return_type.nr_muls() > 0 && typ.nr_muls() > 0 { + typ = typ.set_nr_muls(0) + } } } } else if arg_sym.kind in [.struct_, .interface_, .sum_type] { diff --git a/vlib/v/tests/generic_fn_infer_fn_type_using_ref_arg_test.v b/vlib/v/tests/generic_fn_infer_fn_type_using_ref_arg_test.v new file mode 100644 index 0000000000..a809d45b00 --- /dev/null +++ b/vlib/v/tests/generic_fn_infer_fn_type_using_ref_arg_test.v @@ -0,0 +1,12 @@ +fn test_generic_fn_infer_fn_type_using_ref_arg() { + ret := call_generic_fn(fn (a &int) bool { + return *a > 0 + }, 1) + assert ret +} + +fn call_generic_fn(cb fn (&T) bool, input T) bool { + dump(cb(&input)) + ret := cb(&input) + return ret +}