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:
parent
b93e00ae6b
commit
b61fdfa094
@ -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
|
||||
|
@ -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('*')
|
||||
}
|
||||
|
21
vlib/v/tests/generics_method_variable_test.v
Normal file
21
vlib/v/tests/generics_method_variable_test.v
Normal 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'
|
||||
}
|
Loading…
Reference in New Issue
Block a user