Skip to content

Commit ff452cc

Browse files
authored
cgen: fix interface with multiple embedded fields (#19377)
1 parent be53b02 commit ff452cc

File tree

2 files changed

+49
-5
lines changed

2 files changed

+49
-5
lines changed

vlib/v/gen/c/cgen.v

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6734,11 +6734,21 @@ fn (mut g Gen) interface_table() string {
67346734
cast_struct.write_string('/*.... ast.voidptr_type */')
67356735
} else {
67366736
if st_sym.kind == .struct_ {
6737-
for embed_type in st_sym.struct_info().embeds {
6738-
embed_sym := g.table.sym(embed_type)
6739-
if _ := embed_sym.find_field(field.name) {
6740-
cast_struct.write_string(' + __offsetof_ptr(x, ${cctype}, ${embed_sym.embed_name()}) + __offsetof_ptr(x, ${embed_sym.cname}, ${cname})')
6741-
break
6737+
if _, embeds := g.table.find_field_from_embeds(st_sym,
6738+
field.name)
6739+
{
6740+
mut typ_name := ''
6741+
for i, embed in embeds {
6742+
esym := g.table.sym(embed)
6743+
if i == 0 {
6744+
cast_struct.write_string(' + __offsetof_ptr(x, ${cctype}, ${esym.embed_name()})')
6745+
} else {
6746+
cast_struct.write_string(' + __offsetof_ptr(x, ${typ_name}, ${esym.embed_name()})')
6747+
}
6748+
typ_name = esym.cname
6749+
}
6750+
if embeds.len > 0 {
6751+
cast_struct.write_string(' + __offsetof_ptr(x, ${typ_name}, ${cname})')
67426752
}
67436753
}
67446754
}
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
interface NodeInterface {
2+
mut:
3+
node_type NodeType
4+
node_name string
5+
}
6+
7+
enum NodeType {
8+
@none
9+
}
10+
11+
struct Node {
12+
mut:
13+
// removing this field works makes `InterfaceNode(x).node_name.len` below work as expected
14+
node_type NodeType
15+
node_name string
16+
}
17+
18+
struct Element {
19+
Node
20+
}
21+
22+
struct HTMLElement {
23+
Element
24+
}
25+
26+
fn test_interface_with_multi_nested_embed() {
27+
x := &HTMLElement{}
28+
struct_name_len := x.node_name.len
29+
interface_name_len := NodeInterface(x).node_name.len
30+
println('struct: ${struct_name_len}')
31+
assert struct_name_len == 0
32+
println('interface: ${interface_name_len}')
33+
assert interface_name_len == 0
34+
}

0 commit comments

Comments
 (0)