diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index b284ba72b6..ae0a6cb85e 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5654,17 +5654,23 @@ fn (mut g Gen) interface_table() string { field_styp := g.typ(field.typ) if _ := st_sym.find_field(field.name) { cast_struct.writeln('\t\t.$cname = ($field_styp*)((char*)x + __offsetof_ptr(x, $cctype, $cname)),') + } else if st_sym.kind == .array + && field.name in ['element_size', 'data', 'offset', 'len', 'cap', 'flags'] { + // Manaully checking, we already knows array contains above fields + cast_struct.writeln('\t\t.$cname = ($field_styp*)((char*)x + __offsetof_ptr(x, $cctype, $cname)),') } else { // the field is embedded in another struct cast_struct.write_string('\t\t.$cname = ($field_styp*)((char*)x') if st == ast.voidptr_type { cast_struct.write_string('/*.... ast.voidptr_type */') } else { - 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 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 + } } } } diff --git a/vlib/v/gen/c/testdata/array_as_interface.out b/vlib/v/gen/c/testdata/array_as_interface.out new file mode 100644 index 0000000000..68bd7b8b18 --- /dev/null +++ b/vlib/v/gen/c/testdata/array_as_interface.out @@ -0,0 +1,2 @@ +4 +1 \ No newline at end of file diff --git a/vlib/v/gen/c/testdata/array_as_interface.vv b/vlib/v/gen/c/testdata/array_as_interface.vv new file mode 100644 index 0000000000..e10bb802f4 --- /dev/null +++ b/vlib/v/gen/c/testdata/array_as_interface.vv @@ -0,0 +1,8 @@ +interface Source { + len int +} + +fn main() { + println(Source('test').len) + println(Source([`a`]).len) +} \ No newline at end of file diff --git a/vlib/v/tests/array_as_interface_test.v b/vlib/v/tests/array_as_interface_test.v new file mode 100644 index 0000000000..ba4d041711 --- /dev/null +++ b/vlib/v/tests/array_as_interface_test.v @@ -0,0 +1,19 @@ +interface Source { + element_size int + data voidptr + offset int + len int + cap int + flags ArrayFlags +} + +fn test_array_as_interface() { + arr := []rune{len: 1} + src := Source(arr) + assert arr.element_size == src.element_size + assert arr.data == src.data + assert arr.offset == src.offset + assert arr.len == src.len + assert arr.cap == src.cap + assert arr.flags == src.flags +}