1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: fix nested generic fn call (fix #15328) (#15333)

This commit is contained in:
yuyi 2022-08-03 18:24:39 +08:00 committed by GitHub
parent 77495c8d03
commit 2ad25f6d06
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 27 additions and 4 deletions

View File

@ -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
}

View File

@ -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 {

View File

@ -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

View File

@ -0,0 +1,4 @@
FN: shuffle | T: &[]int
FN: shuffle_impl | T: &[]int
FN: shuffle | T: &[]f64
FN: shuffle_impl | T: &[]f64

View File

@ -0,0 +1,17 @@
module main
fn shuffle_impl<T>(mut a []T) ? {
println('FN: ${@FN:20} | T: ${typeof(a).name}')
}
fn shuffle<T>(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)?
}