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

checker, cgen: fix generic method variable (#18509)

This commit is contained in:
yuyi 2023-06-21 17:09:53 +08:00 committed by GitHub
parent b93e00ae6b
commit b61fdfa094
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 31 additions and 3 deletions

View File

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

View File

@ -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('*')
}

View File

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