mirror of
https://github.com/vlang/v.git
synced 2025-09-17 11:26:17 -04:00
checker: fix f: app.method
field initialisation, for fn fields, initialised with generic methods (#22665)
This commit is contained in:
parent
1ced1e9108
commit
8ffcc34224
@ -1696,7 +1696,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||||||
}
|
}
|
||||||
return field.typ
|
return field.typ
|
||||||
}
|
}
|
||||||
if mut method := sym.find_method_with_generic_parent(field_name) {
|
if mut method := c.table.sym(c.unwrap_generic(typ)).find_method_with_generic_parent(field_name) {
|
||||||
if c.expected_type != 0 && c.expected_type != ast.none_type {
|
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))
|
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
|
// if the expected type includes the receiver, don't hide it behind a closure
|
||||||
@ -1704,7 +1704,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||||||
return fn_type
|
return fn_type
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
receiver := method.params[0].typ
|
receiver := c.unwrap_generic(method.params[0].typ)
|
||||||
if receiver.nr_muls() > 0 {
|
if receiver.nr_muls() > 0 {
|
||||||
if !c.inside_unsafe {
|
if !c.inside_unsafe {
|
||||||
rec_sym := c.table.sym(receiver.set_nr_muls(0))
|
rec_sym := c.table.sym(receiver.set_nr_muls(0))
|
||||||
@ -1723,7 +1723,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
|
|||||||
node.has_hidden_receiver = true
|
node.has_hidden_receiver = true
|
||||||
method.name = ''
|
method.name = ''
|
||||||
fn_type := ast.new_type(c.table.find_or_register_fn_type(method, false, true))
|
fn_type := ast.new_type(c.table.find_or_register_fn_type(method, false, true))
|
||||||
node.typ = fn_type
|
node.typ = c.unwrap_generic(fn_type)
|
||||||
return fn_type
|
return fn_type
|
||||||
}
|
}
|
||||||
if sym.kind !in [.struct, .aggregate, .interface, .sum_type] {
|
if sym.kind !in [.struct, .aggregate, .interface, .sum_type] {
|
||||||
|
@ -4028,7 +4028,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
receiver := m.params[0]
|
receiver := m.params[0]
|
||||||
expr_styp := g.styp(node.expr_type.idx_type())
|
expr_styp := g.styp(g.unwrap_generic(node.expr_type).idx_type())
|
||||||
data_styp := g.styp(receiver.typ.idx_type())
|
data_styp := g.styp(receiver.typ.idx_type())
|
||||||
mut sb := strings.new_builder(256)
|
mut sb := strings.new_builder(256)
|
||||||
name := '_V_closure_${expr_styp}_${m.name}_${node.pos.pos}'
|
name := '_V_closure_${expr_styp}_${m.name}_${node.pos.pos}'
|
||||||
|
24
vlib/v/tests/selector_generic_fn_test.v
Normal file
24
vlib/v/tests/selector_generic_fn_test.v
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
struct Struct {
|
||||||
|
f fn (f64) f64 = unsafe { nil }
|
||||||
|
}
|
||||||
|
|
||||||
|
struct App {}
|
||||||
|
|
||||||
|
pub fn (mut a App) frame(dt f64) f64 {
|
||||||
|
dump(voidptr(a))
|
||||||
|
dump(dt)
|
||||||
|
return dt
|
||||||
|
}
|
||||||
|
|
||||||
|
fn generic_f[T](mut ctx T) ! {
|
||||||
|
s := Struct{
|
||||||
|
f: unsafe { ctx.frame }
|
||||||
|
}
|
||||||
|
assert s.f(1.2) == 1.2
|
||||||
|
}
|
||||||
|
|
||||||
|
fn test_main() {
|
||||||
|
mut app := &App{}
|
||||||
|
generic_f(mut app)!
|
||||||
|
assert true
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user