checker: fix f: app.method field initialisation, for fn fields, initialised with generic methods (#22665)

This commit is contained in:
Felipe Pena 2024-10-27 15:43:15 -03:00 committed by GitHub
parent 1ced1e9108
commit 8ffcc34224
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 28 additions and 4 deletions

View File

@ -1696,7 +1696,7 @@ 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
@ -1704,7 +1704,7 @@ fn (mut c Checker) selector_expr(mut node ast.SelectorExpr) ast.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))
@ -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] {

View File

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

View 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
}