From 104eb25a878ce7f17b5f9a26d4a2c09b5e7d23c4 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Mon, 29 Jul 2024 01:18:47 -0300 Subject: [PATCH] cgen: fix generic sumtype with repeated concrete type (#21948) --- vlib/v/gen/c/auto_str_methods.v | 5 +++++ vlib/v/gen/c/cgen.v | 20 ++++++++++++++++++++ vlib/v/tests/generic_sumtype_repeated_test.v | 7 +++++++ 3 files changed, 32 insertions(+) create mode 100644 vlib/v/tests/generic_sumtype_repeated_test.v diff --git a/vlib/v/gen/c/auto_str_methods.v b/vlib/v/gen/c/auto_str_methods.v index 01a8f1fc6c..456d34cdc5 100644 --- a/vlib/v/gen/c/auto_str_methods.v +++ b/vlib/v/gen/c/auto_str_methods.v @@ -442,7 +442,12 @@ fn (mut g Gen) gen_str_for_union_sum_type(info ast.SumType, styp string, typ_str clean_sum_type_v_type_name = util.strip_main_name(typ_str) } fn_builder.writeln('\tswitch(x._typ) {') + mut idxs := []int{} for typ in info.variants { + if typ in idxs { + continue + } + idxs << typ typ_name := g.typ(typ) mut func_name := g.get_str_fn(typ) sym := g.table.sym(typ) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index d63c5c7718..d8b9fa1c9c 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1000,9 +1000,14 @@ pub fn (mut g Gen) write_typeof_functions() { tidx := g.table.find_type_idx(sym.name) g.writeln('\tswitch(sidx) {') g.writeln('\t\tcase ${tidx}: return "${util.strip_main_name(sym.name)}";') + mut idxs := []int{} for v in sum_info.variants { + if v in idxs { + continue + } subtype := g.table.sym(v) g.writeln('\t\tcase ${int(v)}: return "${util.strip_main_name(subtype.name)}";') + idxs << v } g.writeln('\t\tdefault: return "unknown ${util.strip_main_name(sym.name)}";') g.writeln('\t}') @@ -1021,8 +1026,13 @@ pub fn (mut g Gen) write_typeof_functions() { tidx := g.table.find_type_idx(sym.name) g.writeln('\tswitch(sidx) {') g.writeln('\t\tcase ${tidx}: return ${int(ityp)};') + mut idxs := []int{} for v in sum_info.variants { + if v in idxs { + continue + } g.writeln('\t\tcase ${int(v)}: return ${int(v)};') + idxs << v } g.writeln('\t\tdefault: return ${int(ityp)};') g.writeln('\t}') @@ -6678,12 +6688,22 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) { g.typedefs.writeln('typedef struct ${name} ${name};') g.type_definitions.writeln('') g.type_definitions.writeln('// Union sum type ${name} = ') + mut idxs := []int{} for variant in sym.info.variants { + if variant in idxs { + continue + } g.type_definitions.writeln('// | ${variant:4d} = ${g.typ(variant.idx()):-20s}') + idxs << variant } + idxs.clear() g.type_definitions.writeln('struct ${name} {') g.type_definitions.writeln('\tunion {') for variant in sym.info.variants { + if variant in idxs { + continue + } + idxs << variant variant_sym := g.table.sym(variant) mut var := if variant.has_flag(.option) { variant } else { variant.ref() } variant_name := g.get_sumtype_variant_name(variant, variant_sym) diff --git a/vlib/v/tests/generic_sumtype_repeated_test.v b/vlib/v/tests/generic_sumtype_repeated_test.v new file mode 100644 index 0000000000..3a90e182c2 --- /dev/null +++ b/vlib/v/tests/generic_sumtype_repeated_test.v @@ -0,0 +1,7 @@ +type Name[T] = T | int | string + +fn test_main() { + a := Name[int](123) + assert dump(a) == Name[int](123) + println(a) +}