checker, cgen: fix error for struct embed with fn type (#13450)
parent
4391ae563d
commit
b5379255da
|
@ -1424,7 +1424,7 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||
}
|
||||
// call struct field fn type
|
||||
// TODO: can we use SelectorExpr for all? this dosent really belong here
|
||||
if field := c.table.find_field(left_sym, method_name) {
|
||||
if field := c.table.find_field_with_embeds(left_sym, method_name) {
|
||||
field_sym := c.table.sym(c.unwrap_generic(field.typ))
|
||||
if field_sym.kind == .function {
|
||||
node.is_method = false
|
||||
|
@ -1453,6 +1453,9 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||
}
|
||||
node.expected_arg_types = earg_types
|
||||
node.is_method = true
|
||||
_, node.from_embed_types = c.table.find_field_from_embeds(left_sym, method_name) or {
|
||||
return info.func.return_type
|
||||
}
|
||||
return info.func.return_type
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1118,6 +1118,16 @@ fn (mut g Gen) fn_call(node ast.CallExpr) {
|
|||
} else {
|
||||
g.write('.')
|
||||
}
|
||||
for embed in node.from_embed_types {
|
||||
embed_sym := g.table.sym(embed)
|
||||
embed_name := embed_sym.embed_name()
|
||||
g.write(embed_name)
|
||||
if embed.is_ptr() {
|
||||
g.write('->')
|
||||
} else {
|
||||
g.write('.')
|
||||
}
|
||||
}
|
||||
is_selector_call = true
|
||||
}
|
||||
if g.inside_comptime_for_field {
|
||||
|
|
|
@ -0,0 +1,29 @@
|
|||
type FnClick = fn () string
|
||||
|
||||
struct Widget {
|
||||
mut:
|
||||
x int
|
||||
y int
|
||||
click FnClick = click
|
||||
}
|
||||
|
||||
fn click() string {
|
||||
return 'click me'
|
||||
}
|
||||
|
||||
struct Button {
|
||||
Widget
|
||||
title string
|
||||
}
|
||||
|
||||
fn test_struct_embed_fn_type() {
|
||||
mut button := Button{
|
||||
title: 'Click me'
|
||||
}
|
||||
|
||||
button.x = 3
|
||||
ret := button.click()
|
||||
|
||||
println(ret)
|
||||
assert ret == 'click me'
|
||||
}
|
Loading…
Reference in New Issue