cgen: fix array type as interface (fix #14677) (#14681)

ChAoS_UnItY 2022-06-05 10:05:48 +08:00 committed by Chewing_Bever
parent a4829f64e8
commit a0f1c1ffef
Signed by: Jef Roosens
GPG Key ID: B75D4F293C7052DB
4 changed files with 40 additions and 5 deletions

View File

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

View File

@ -0,0 +1,2 @@
4
1

View File

@ -0,0 +1,8 @@
interface Source {
len int
}
fn main() {
println(Source('test').len)
println(Source([`a`]).len)
}

View File

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