Skip to content

Commit

Permalink
cgen: fix interface with multiple embedded fields (#19377)
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 authored Sep 18, 2023
1 parent be53b02 commit ff452cc
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
20 changes: 15 additions & 5 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -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})')
}
}
}
Expand Down
34 changes: 34 additions & 0 deletions vlib/v/tests/interface_with_multi_nested_embed_3_test.v
Original file line number Diff line number Diff line change
@@ -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
}

0 comments on commit ff452cc

Please sign in to comment.