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

checker: fix generic argument resolution when mixed order on next call (#18192)

This commit is contained in:
Felipe Pena 2023-05-18 06:24:06 -03:00 committed by GitHub
parent 2c95b9be32
commit 273f46f810
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 26 additions and 1 deletions

View File

@ -848,6 +848,7 @@ fn (g Checker) get_generic_array_fixed_element_type(array ast.ArrayFixed) ast.Ty
fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) { fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
mut inferred_types := []ast.Type{} mut inferred_types := []ast.Type{}
mut arg_inferred := []int{}
for gi, gt_name in func.generic_names { for gi, gt_name in func.generic_names {
// skip known types // skip known types
if gi < node.concrete_types.len { if gi < node.concrete_types.len {
@ -1027,7 +1028,7 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
} }
} else if arg_sym.kind == .any && c.table.cur_fn.generic_names.len > 0 } else if arg_sym.kind == .any && c.table.cur_fn.generic_names.len > 0
&& c.table.cur_fn.params.len > 0 && func.generic_names.len > 0 && c.table.cur_fn.params.len > 0 && func.generic_names.len > 0
&& arg.expr is ast.Ident { && arg.expr is ast.Ident && arg_i !in arg_inferred {
var_name := (arg.expr as ast.Ident).name var_name := (arg.expr as ast.Ident).name
for k, cur_param in c.table.cur_fn.params { for k, cur_param in c.table.cur_fn.params {
if !cur_param.typ.has_flag(.generic) || k < gi || cur_param.name != var_name { if !cur_param.typ.has_flag(.generic) || k < gi || cur_param.name != var_name {
@ -1045,6 +1046,9 @@ fn (mut c Checker) infer_fn_generic_types(func ast.Fn, mut node ast.CallExpr) {
} }
} }
} }
if typ != ast.void_type {
arg_inferred << arg_i
}
} }
if typ == ast.void_type { if typ == ast.void_type {
c.error('could not infer generic type `${gt_name}` in call to `${func.name}`', c.error('could not infer generic type `${gt_name}` in call to `${func.name}`',

View File

@ -0,0 +1,21 @@
struct MyStruct {
text string
}
struct App {}
fn pre_send[T, N](app T, params N) {
send(params, app)
}
fn send[T, N](params T, app N) { // app now is second argument
println(params)
}
fn test_main() {
params := MyStruct{'hello'}
app := App{}
pre_send(app, params)
assert true
}