From 2ad25f6d067cb3d312154e31f9d686436469351a Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 3 Aug 2022 18:24:39 +0800 Subject: [PATCH] checker: fix nested generic fn call (fix #15328) (#15333) --- vlib/v/checker/check_types.v | 5 ++--- vlib/v/checker/fn.v | 2 +- vlib/v/gen/c/cgen.v | 3 +++ vlib/v/tests/inout/nested_generic_fn_call.out | 4 ++++ vlib/v/tests/inout/nested_generic_fn_call.vv | 17 +++++++++++++++++ 5 files changed, 27 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/inout/nested_generic_fn_call.out create mode 100644 vlib/v/tests/inout/nested_generic_fn_call.vv diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index d5420627b9..9b7184e06e 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -648,8 +648,7 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr if node.args.len <= arg_i { break } - mut arg := node.args[arg_i] - arg.typ = c.unwrap_generic(arg.typ) + arg := node.args[arg_i] param_type_sym := c.table.sym(param.typ) if param.typ.has_flag(.generic) && param_type_sym.name == gt_name { @@ -787,7 +786,7 @@ pub fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr s := c.table.type_to_str(typ) println('inferred `$func.name<$s>`') } - inferred_types << typ + inferred_types << c.unwrap_generic(typ) node.concrete_types << typ } diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 512799c340..d1605fd99e 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -1033,7 +1033,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) if func.generic_names.len != node.concrete_types.len { // no type arguments given in call, attempt implicit instantiation c.infer_fn_generic_types(func, mut node) - concrete_types = node.concrete_types + concrete_types = node.concrete_types.map(c.unwrap_generic(it)) } if func.generic_names.len > 0 { for i, mut call_arg in node.args { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 2ba3c79ad8..6ddd14c03d 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1440,6 +1440,9 @@ pub fn (mut g Gen) write_multi_return_types() { if sym.kind != .multi_return { continue } + if sym.cname.contains('<') { + continue + } info := sym.mr_info() if info.types.filter(it.has_flag(.generic)).len > 0 { continue diff --git a/vlib/v/tests/inout/nested_generic_fn_call.out b/vlib/v/tests/inout/nested_generic_fn_call.out new file mode 100644 index 0000000000..85697a2e00 --- /dev/null +++ b/vlib/v/tests/inout/nested_generic_fn_call.out @@ -0,0 +1,4 @@ +FN: shuffle | T: &[]int +FN: shuffle_impl | T: &[]int +FN: shuffle | T: &[]f64 +FN: shuffle_impl | T: &[]f64 diff --git a/vlib/v/tests/inout/nested_generic_fn_call.vv b/vlib/v/tests/inout/nested_generic_fn_call.vv new file mode 100644 index 0000000000..6e6df5476a --- /dev/null +++ b/vlib/v/tests/inout/nested_generic_fn_call.vv @@ -0,0 +1,17 @@ +module main + +fn shuffle_impl(mut a []T) ? { + println('FN: ${@FN:20} | T: ${typeof(a).name}') +} + +fn shuffle(mut a []T) ? { + println('FN: ${@FN:20} | T: ${typeof(a).name}') + shuffle_impl(mut a)? +} + +fn main() { + mut a := [1, 2] + mut b := [f64(1.0), 2.0] + shuffle(mut a)? + shuffle(mut b)? +}