diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index b710ac013e..94eebc4311 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1484,7 +1484,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type { } return field.typ } - if mut method := c.table.find_method(sym, field_name) { + if mut method := sym.find_method_with_generic_parent(field_name) { if c.expected_type != 0 && c.expected_type != ast.none_type { fn_type := ast.new_type(c.table.find_or_register_fn_type(method, false, true)) // if the expected type includes the receiver, don't hide it behind a closure diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index cea9960ece..41bbb0c60b 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -3619,7 +3619,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } } } - } else if m := g.table.find_method(sym, node.field_name) { + } else if m := sym.find_method_with_generic_parent(node.field_name) { mut has_embeds := false if sym.info in [ast.Struct, ast.Aggregate] { if node.from_embed_types.len > 0 { @@ -3651,7 +3651,14 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) { } else { sb.write_string('\t') } - sb.write_string('${expr_styp}_${m.name}(') + mut method_name := m.name + rec_sym := g.table.sym(receiver.typ) + if rec_sym.info is ast.Struct { + if rec_sym.info.concrete_types.len > 0 { + method_name = g.generic_fn_name(rec_sym.info.concrete_types, m.name) + } + } + sb.write_string('${expr_styp}_${method_name}(') if !receiver.typ.is_ptr() { sb.write_string('*') } diff --git a/vlib/v/tests/generics_method_variable_test.v b/vlib/v/tests/generics_method_variable_test.v new file mode 100644 index 0000000000..96fc846d34 --- /dev/null +++ b/vlib/v/tests/generics_method_variable_test.v @@ -0,0 +1,21 @@ +type Func = fn (string) string + +struct Struct[T] { + a T +mut: + func Func +} + +fn (st Struct[T]) foo[T](s string) string { + println('${st.a} - ${s}') + return '${st.a} - ${s}' +} + +fn test_generic_method_variable() { + mut st := Struct[int]{ + a: 22 + } + st.func = st.foo + ret := st.func('hello') + assert ret == '22 - hello' +}