From 8b085a32a54829b27ed4f7db7aa0d19b8063602b Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 27 Apr 2022 16:32:43 +0800 Subject: [PATCH] cgen: fix error for generic sumtype casting to typenode (#14188) --- vlib/v/gen/c/cgen.v | 12 +++--- vlib/v/tests/generic_sumtype_cast_test.v | 50 ++++++++++++++++++++++++ 2 files changed, 56 insertions(+), 6 deletions(-) create mode 100644 vlib/v/tests/generic_sumtype_cast_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index f349bb51db..69dd1d3339 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -5207,9 +5207,10 @@ fn (mut g Gen) as_cast(node ast.AsCast) { // Make sure the sum type can be cast to this type (the types // are the same), otherwise panic. // g.insert_before(' - styp := g.typ(node.typ) - sym := g.table.sym(node.typ) - mut expr_type_sym := g.table.sym(node.expr_type) + unwrapped_node_typ := g.unwrap_generic(node.typ) + styp := g.typ(unwrapped_node_typ) + sym := g.table.sym(unwrapped_node_typ) + mut expr_type_sym := g.table.sym(g.unwrap_generic(node.expr_type)) if mut expr_type_sym.info is ast.SumType { dot := if node.expr_type.is_ptr() { '->' } else { '.' } g.write('/* as */ *($styp*)__as_cast(') @@ -5223,9 +5224,8 @@ fn (mut g Gen) as_cast(node ast.AsCast) { g.write(')') g.write(dot) // g.write('typ, /*expected:*/$node.typ)') - sidx := g.type_sidx(node.typ) - expected_sym := g.table.sym(node.typ) - g.write('_typ, $sidx) /*expected idx: $sidx, name: $expected_sym.name */ ') + sidx := g.type_sidx(unwrapped_node_typ) + g.write('_typ, $sidx) /*expected idx: $sidx, name: $sym.name */ ') // fill as cast name table for variant in expr_type_sym.info.variants { diff --git a/vlib/v/tests/generic_sumtype_cast_test.v b/vlib/v/tests/generic_sumtype_cast_test.v new file mode 100644 index 0000000000..902fcd53d1 --- /dev/null +++ b/vlib/v/tests/generic_sumtype_cast_test.v @@ -0,0 +1,50 @@ +module main + +struct Empty {} + +struct Node { + value T +mut: + next Tree +} + +type Tree = Empty | Node + +fn create() Tree { + empty := Empty{} + mut curr := Node{10, empty} + for _ in 0 .. 10 { + curr.next = Node{20, empty} + } + + return curr +} + +fn create_node(args []T) Tree { + empty := Empty{} + if args.len == 0 { + return empty + } + + mut curr := Node{args[0], empty} + + for i := 1; i < args.len; i += 1 { + curr.next = Node{args[i], empty} + curr = curr.next as Node + } + + return curr +} + +fn merge_nodes(head Tree) Tree { + println('$head') + + return Empty{} +} + +fn test_generic_sumtype_cast() { + node := create_node([0, 3, 1, 0, 4, 5, 2, 0]) + merge_nodes(node) + create() + assert true +}