From 9825c7e06c1fa87ee729d31f080396afd049c6f8 Mon Sep 17 00:00:00 2001 From: yuyi Date: Mon, 29 Nov 2021 21:12:00 +0800 Subject: [PATCH] ast: fix generic sumtype of alias generic struct (#12611) --- vlib/v/ast/table.v | 15 +++++--- ...ric_sumtype_of_alias_generic_struct_test.v | 35 +++++++++++++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 vlib/v/tests/generic_sumtype_of_alias_generic_struct_test.v diff --git a/vlib/v/ast/table.v b/vlib/v/ast/table.v index 1e217502fa..47ec5c9f8f 100644 --- a/vlib/v/ast/table.v +++ b/vlib/v/ast/table.v @@ -362,14 +362,15 @@ pub struct GetEmbedsOptions { // the hierarchy of embeds is returned as a list pub fn (t &Table) get_embeds(sym &TypeSymbol, options GetEmbedsOptions) [][]Type { mut embeds := [][]Type{} - if sym.info is Struct { - for embed in sym.info.embeds { + unalias_sym := if sym.info is Alias { t.get_type_symbol(sym.info.parent_type) } else { sym } + if unalias_sym.info is Struct { + for embed in unalias_sym.info.embeds { embed_sym := t.get_type_symbol(embed) mut preceding := options.preceding preceding << embed embeds << t.get_embeds(embed_sym, preceding: preceding) } - if sym.info.embeds.len == 0 && options.preceding.len > 0 { + if unalias_sym.info.embeds.len == 0 && options.preceding.len > 0 { embeds << options.preceding } } @@ -527,6 +528,9 @@ pub fn (t &Table) find_field_from_embeds_recursive(sym &TypeSymbol, field_name s return field, embed_types } } + } else if sym.info is Alias { + unalias_sym := t.get_type_symbol(sym.info.parent_type) + return t.find_field_from_embeds_recursive(unalias_sym, field_name) } return none } @@ -556,6 +560,9 @@ pub fn (t &Table) find_field_from_embeds(sym &TypeSymbol, field_name string) ?(S return field, embed_type } } + } else if sym.info is Alias { + unalias_sym := t.get_type_symbol(sym.info.parent_type) + return t.find_field_from_embeds(unalias_sym, field_name) } return none } @@ -581,7 +588,7 @@ pub fn (t &Table) resolve_common_sumtype_fields(sym_ &TypeSymbol) { mut field_map := map[string]StructField{} mut field_usages := map[string]int{} for variant in info.variants { - mut v_sym := t.get_type_symbol(variant) + mut v_sym := t.get_final_type_symbol(variant) fields := match mut v_sym.info { Struct { t.struct_fields(v_sym) diff --git a/vlib/v/tests/generic_sumtype_of_alias_generic_struct_test.v b/vlib/v/tests/generic_sumtype_of_alias_generic_struct_test.v new file mode 100644 index 0000000000..5bf3f487a5 --- /dev/null +++ b/vlib/v/tests/generic_sumtype_of_alias_generic_struct_test.v @@ -0,0 +1,35 @@ +struct Shared { + val int +} + +struct AA { + Shared +} + +type AAint = AA +type AAbool = AA + +struct BB { + Shared +} + +type BBint = BB +type BBbool = BB + +type CC = AAbool | AAint | BBbool | BBint + +fn (c CC) str() string { + return '$c.val' +} + +fn test_generic_sumtype_of_alias_generic_struct() { + mut c := []CC{} + c << AAint{ + val: 1 + } + c << BBbool{ + val: 2 + } + println('$c') + assert '$c' == '[1, 2]' +}