Skip to content

Commit

Permalink
fix
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp committed Dec 21, 2024
1 parent 80d8c85 commit 81a6e34
Show file tree
Hide file tree
Showing 2 changed files with 50 additions and 9 deletions.
25 changes: 16 additions & 9 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -1806,15 +1806,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
}
if mut call_arg.expr is ast.LambdaExpr {
// Calling fn is generic and lambda arg also is generic
if node.concrete_types.len > 0 && call_arg.expr.func != unsafe { nil }
&& call_arg.expr.func.decl.generic_names.len > 0 {
call_arg.expr.call_ctx = unsafe { node }
if c.table.register_fn_concrete_types(call_arg.expr.func.decl.fkey(),
node.concrete_types)
{
call_arg.expr.func.decl.ninstances++
}
}
c.handle_generic_lambda_arg(node, mut call_arg.expr)
continue
}
c.error('${err.msg()} in argument ${i + 1} to `${fn_name}`', call_arg.pos)
Expand Down Expand Up @@ -2793,6 +2785,10 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
c.error('${err.msg()} in argument ${i + 1} to `${left_sym.name}.${method_name}`',
arg.pos)
}
if mut arg.expr is ast.LambdaExpr {
// Calling fn is generic and lambda arg also is generic
c.handle_generic_lambda_arg(node, mut arg.expr)
}
param_typ_sym := c.table.sym(exp_arg_typ)
if param_typ_sym.kind == .struct && got_arg_typ !in [ast.voidptr_type, ast.nil_type]
&& !c.check_multiple_ptr_match(got_arg_typ, param.typ, param, arg) {
Expand Down Expand Up @@ -2871,6 +2867,17 @@ fn (mut c Checker) method_call(mut node ast.CallExpr, mut continue_check &bool)
return node.return_type
}

fn (mut c Checker) handle_generic_lambda_arg(node &ast.CallExpr, mut lambda ast.LambdaExpr) {
// Calling fn is generic and lambda arg also is generic
if node.concrete_types.len > 0 && lambda.func != unsafe { nil }
&& lambda.func.decl.generic_names.len > 0 {
lambda.call_ctx = unsafe { node }
if c.table.register_fn_concrete_types(lambda.func.decl.fkey(), node.concrete_types) {
lambda.func.decl.ninstances++
}
}
}

fn (mut c Checker) spawn_expr(mut node ast.SpawnExpr) ast.Type {
ret_type := c.call_expr(mut node.call_expr)
if node.call_expr.or_block.kind != .absent {
Expand Down
34 changes: 34 additions & 0 deletions vlib/v/tests/generics/generic_method_lambda_arg_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
module main

fn test_main() {
my := MyError{
path: 'err msg'
}
p := my.to[string](|m| m.path)
p2 := my.to_str(|m| m.path)
println(p)
println(p2)

assert p == p2
}

struct MyError {
pub:
path string
}

fn (e &MyError) msg() string {
return e.path
}

fn (e &MyError) code() int {
return 1
}

fn (e &MyError) to[T](func fn (MyError) T) T {
return func(e)
}

fn (e &MyError) to_str(func fn (MyError) string) string {
return func(e)
}

0 comments on commit 81a6e34

Please sign in to comment.