diff --git a/vlib/v/parser/parser.v b/vlib/v/parser/parser.v index 78a3df1887..a109376ea7 100644 --- a/vlib/v/parser/parser.v +++ b/vlib/v/parser/parser.v @@ -1837,11 +1837,13 @@ fn (p mut Parser) type_decl() ast.TypeDecl { p.check(.key_type) name := p.check_name() mut is_sum := false + mut sum_variants := []table.Type // type SumType = A | B | c if p.tok.kind == .assign { p.next() for { - p.check_name() + variant_type := p.parse_type() + sum_variants << variant_type if p.tok.kind != .pipe { break } @@ -1852,13 +1854,23 @@ fn (p mut Parser) type_decl() ast.TypeDecl { else { p.parse_type() } - p.table.register_type_symbol(table.TypeSymbol{ - kind: .sum_type - name: name - info: table.Alias{ - foo: '' - } - }) + if is_sum { + p.table.register_type_symbol(table.TypeSymbol{ + kind: .sum_type + name: p.prepend_mod(name) + info: table.SumType{ + variants: sum_variants + } + }) + } else { + p.table.register_type_symbol(table.TypeSymbol{ + kind: .alias + name: p.prepend_mod(name) + info: table.Alias{ + foo: '' + } + }) + } return ast.TypeDecl{ name: name } diff --git a/vlib/v/table/atype_symbols.v b/vlib/v/table/atype_symbols.v index a72d186788..c7858b724a 100644 --- a/vlib/v/table/atype_symbols.v +++ b/vlib/v/table/atype_symbols.v @@ -8,7 +8,7 @@ import ( ) pub type TypeInfo = Array | ArrayFixed | Map | Struct | -MultiReturn | Alias | Enum +MultiReturn | Alias | Enum | SumType pub struct TypeSymbol { pub: @@ -399,6 +399,10 @@ pub mut: value_type Type } +pub struct SumType { + variants []Type +} + pub fn (table &Table) type_to_str(t Type) string { sym := table.get_type_symbol(t) if sym.kind == .multi_return { diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 9f89f720a3..4d84b6e327 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -413,6 +413,19 @@ pub fn (t &Table) check(got, expected Type) bool { if got_type_sym.kind == .array && got_type_sym.name == 'array_void' && exp_type_sym.kind == .array { return true } + // sum type + if got_type_sym.kind == .sum_type { + sum_info := got_type_sym.info as SumType + if expected in sum_info.variants { + return true + } + } + else if exp_type_sym.kind == .sum_type { + sum_info := exp_type_sym.info as SumType + if got in sum_info.variants { + return true + } + } if got_idx != exp_idx { // && got.typ.name != expected.typ.name*/ return false diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index f7af950f99..c706e4bb97 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -8,6 +8,15 @@ pub enum TypeExtra { variadic } +pub fn (types []Type) contains(typ Type) bool { + for t in types { + if int(typ) == int(t) { + return true + } + } + return false +} + // return underlying TypeSymbol idx [inline] pub fn type_idx(t Type) int {