cgen: fix interface with multiple embedded fields (#19377)

This commit is contained in:
yuyi 2023-09-19 04:22:19 +08:00 committed by GitHub
parent be53b02511
commit ff452cc514
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 49 additions and 5 deletions

View File

@ -6734,11 +6734,21 @@ fn (mut g Gen) interface_table() string {
cast_struct.write_string('/*.... ast.voidptr_type */')
} else {
if st_sym.kind == .struct_ {
for embed_type in st_sym.struct_info().embeds {
embed_sym := g.table.sym(embed_type)
if _ := embed_sym.find_field(field.name) {
cast_struct.write_string(' + __offsetof_ptr(x, ${cctype}, ${embed_sym.embed_name()}) + __offsetof_ptr(x, ${embed_sym.cname}, ${cname})')
break
if _, embeds := g.table.find_field_from_embeds(st_sym,
field.name)
{
mut typ_name := ''
for i, embed in embeds {
esym := g.table.sym(embed)
if i == 0 {
cast_struct.write_string(' + __offsetof_ptr(x, ${cctype}, ${esym.embed_name()})')
} else {
cast_struct.write_string(' + __offsetof_ptr(x, ${typ_name}, ${esym.embed_name()})')
}
typ_name = esym.cname
}
if embeds.len > 0 {
cast_struct.write_string(' + __offsetof_ptr(x, ${typ_name}, ${cname})')
}
}
}

View File

@ -0,0 +1,34 @@
interface NodeInterface {
mut:
node_type NodeType
node_name string
}
enum NodeType {
@none
}
struct Node {
mut:
// removing this field works makes `InterfaceNode(x).node_name.len` below work as expected
node_type NodeType
node_name string
}
struct Element {
Node
}
struct HTMLElement {
Element
}
fn test_interface_with_multi_nested_embed() {
x := &HTMLElement{}
struct_name_len := x.node_name.len
interface_name_len := NodeInterface(x).node_name.len
println('struct: ${struct_name_len}')
assert struct_name_len == 0
println('interface: ${interface_name_len}')
assert interface_name_len == 0
}