diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 6840fe67bf..b163675509 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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) + } } } } diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 174b1c6780..78e5d99ada 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -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 diff --git a/vlib/v/checker/tests/struct_embed_invalid_type.out b/vlib/v/checker/tests/struct_embed_invalid_type.out index d85190fa35..f7622b52c4 100644 --- a/vlib/v/checker/tests/struct_embed_invalid_type.out +++ b/vlib/v/checker/tests/struct_embed_invalid_type.out @@ -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 | } \ No newline at end of file + 5 | } diff --git a/vlib/v/tests/anon_struct_alias_type_decl_embed_test.v b/vlib/v/tests/anon_struct_alias_type_decl_embed_test.v new file mode 100644 index 0000000000..bc6c1df484 --- /dev/null +++ b/vlib/v/tests/anon_struct_alias_type_decl_embed_test.v @@ -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 +}