checker, cgen: fix error for struct embed with fn type (#13450)

pull/13454/head
yuyi 2022-02-13 02:55:40 +08:00 committed by GitHub
parent 4391ae563d
commit b5379255da
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 43 additions and 1 deletions

View File

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

View File

@ -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 {

View File

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