checker: allow embed of type alias anon struct (#21928)

This commit is contained in:
Swastik Baranwal 2024-07-25 07:51:23 +05:30 committed by GitHub
parent eb63cda0a9
commit b2a38346e2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 36 additions and 7 deletions

View File

@ -571,9 +571,12 @@ fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
}
if parent_typ_sym.info.is_anon {
for field in parent_typ_sym.info.fields {
if c.table.final_sym(field.typ).kind != .struct_ {
c.error('cannot embed non-struct `${c.table.sym(field.typ).name}`',
field.type_pos)
field_sym := c.table.sym(field.typ)
if field_sym.info is ast.Alias {
if c.table.sym(field_sym.info.parent_type).kind != .struct_ {
c.error('cannot embed non-struct `${field_sym.name}`',
field.type_pos)
}
}
}
}

View File

@ -26,7 +26,13 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
}
for embed in node.embeds {
embed_sym := c.table.sym(embed.typ)
if embed_sym.kind != .struct_ {
if embed_sym.info is ast.Alias {
parent_sym := c.table.sym(embed_sym.info.parent_type)
if parent_sym.kind != .struct_ {
c.error('`${embed_sym.name}` (alias of `${parent_sym.name}`) is not a struct',
embed.pos)
}
} else if embed_sym.kind != .struct_ {
c.error('`${embed_sym.name}` is not a struct', embed.pos)
} else if (embed_sym.info as ast.Struct).is_heap && !embed.typ.is_ptr() {
struct_sym.info.is_heap = true

View File

@ -1,6 +1,6 @@
vlib/v/checker/tests/struct_embed_invalid_type.vv:4:2: error: `Foo` is not a struct
2 |
vlib/v/checker/tests/struct_embed_invalid_type.vv:4:2: error: `Foo` (alias of `int`) is not a struct
2 |
3 | struct Bar {
4 | Foo
| ~~~
5 | }
5 | }

View File

@ -0,0 +1,20 @@
type AnonStruct = struct {
a int
b int
c int
}
struct Abc {
AnonStruct
}
fn test_anon_struct_type_alias_decl_embed() {
abc := Abc{AnonStruct(struct {10, 20, 30})}
assert abc.a == 10
assert abc.b == 20
assert abc.c == 30
assert abc.AnonStruct.a == 10
assert abc.AnonStruct.b == 20
assert abc.AnonStruct.c == 30
}