mirror of
https://github.com/vlang/v.git
synced 2025-09-10 16:00:31 -04:00
checker: allow embed of type alias anon struct (#21928)
This commit is contained in:
parent
eb63cda0a9
commit
b2a38346e2
@ -571,14 +571,17 @@ fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
|
|||||||
}
|
}
|
||||||
if parent_typ_sym.info.is_anon {
|
if parent_typ_sym.info.is_anon {
|
||||||
for field in parent_typ_sym.info.fields {
|
for field in parent_typ_sym.info.fields {
|
||||||
if c.table.final_sym(field.typ).kind != .struct_ {
|
field_sym := c.table.sym(field.typ)
|
||||||
c.error('cannot embed non-struct `${c.table.sym(field.typ).name}`',
|
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)
|
field.type_pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
.array {
|
.array {
|
||||||
c.check_alias_vs_element_type_of_parent(node, (parent_typ_sym.info as ast.Array).elem_type,
|
c.check_alias_vs_element_type_of_parent(node, (parent_typ_sym.info as ast.Array).elem_type,
|
||||||
'array')
|
'array')
|
||||||
|
@ -26,7 +26,13 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) {
|
|||||||
}
|
}
|
||||||
for embed in node.embeds {
|
for embed in node.embeds {
|
||||||
embed_sym := c.table.sym(embed.typ)
|
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)
|
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() {
|
} else if (embed_sym.info as ast.Struct).is_heap && !embed.typ.is_ptr() {
|
||||||
struct_sym.info.is_heap = true
|
struct_sym.info.is_heap = true
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
vlib/v/checker/tests/struct_embed_invalid_type.vv:4:2: error: `Foo` is not a struct
|
vlib/v/checker/tests/struct_embed_invalid_type.vv:4:2: error: `Foo` (alias of `int`) is not a struct
|
||||||
2 |
|
2 |
|
||||||
3 | struct Bar {
|
3 | struct Bar {
|
||||||
4 | Foo
|
4 | Foo
|
||||||
|
20
vlib/v/tests/anon_struct_alias_type_decl_embed_test.v
Normal file
20
vlib/v/tests/anon_struct_alias_type_decl_embed_test.v
Normal 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
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user