Skip to content

Commit

Permalink
checker: fix f: app.method field initialisation, for fn fields, ini…
Browse files Browse the repository at this point in the history
…tialised with generic methods (#22665)
  • Loading branch information
felipensp authored Oct 27, 2024
1 parent 1ced1e9 commit 8ffcc34
Show file tree
Hide file tree
Showing 3 changed files with 28 additions and 4 deletions.
6 changes: 3 additions & 3 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -1696,15 +1696,15 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
}
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 {
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 c.check_types(fn_type, c.expected_type) {
return fn_type
}
}
receiver := method.params[0].typ
receiver := c.unwrap_generic(method.params[0].typ)
if receiver.nr_muls() > 0 {
if !c.inside_unsafe {
rec_sym := c.table.sym(receiver.set_nr_muls(0))
Expand All @@ -1723,7 +1723,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.Type {
node.has_hidden_receiver = true
method.name = ''
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
}
if sym.kind !in [.struct, .aggregate, .interface, .sum_type] {
Expand Down
2 changes: 1 addition & 1 deletion vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -4028,7 +4028,7 @@ fn (mut g Gen) selector_expr(node ast.SelectorExpr) {
return
}
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())
mut sb := strings.new_builder(256)
name := '_V_closure_${expr_styp}_${m.name}_${node.pos.pos}'
Expand Down
24 changes: 24 additions & 0 deletions vlib/v/tests/selector_generic_fn_test.v
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit 8ffcc34

Please sign in to comment.