From 4d6b8cbfd81939bb7abd865b914a8acacf343916 Mon Sep 17 00:00:00 2001 From: yuyi Date: Wed, 31 Aug 2022 15:45:47 +0800 Subject: [PATCH] cgen: fix casting sumtype as fntype (#15612) --- vlib/v/gen/c/cgen.v | 5 ++- vlib/v/tests/inout/sumtype_with_fntype.out | 8 +++-- vlib/v/tests/inout/sumtype_with_fntype.vv | 37 ++++++++++++++++------ 3 files changed, 38 insertions(+), 12 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 29efaaf00..2919ba0e1 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2103,9 +2103,12 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) { got, exp := fun.got, fun.exp got_sym, exp_sym := g.table.sym(got), g.table.sym(exp) mut got_cname, exp_cname := got_sym.cname, exp_sym.cname + mut type_idx := g.type_sidx(got) if got_sym.info is ast.FnType { if got_sym.info.is_anon { + got_name := 'fn ${g.table.fn_type_source_signature(got_sym.info.func)}' got_cname = 'anon_fn_${g.table.fn_type_signature(got_sym.info.func)}' + type_idx = g.table.type_idxs[got_name].str() } } mut sb := strings.new_builder(128) @@ -2128,7 +2131,7 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) { // if the variable is not used, the C compiler will optimize it away sb.writeln('\t$embed_cname* ${embed_name}_ptr = memdup($accessor, sizeof($embed_cname));') } - sb.write_string('\treturn ($exp_cname){ ._$got_cname = ptr, ._typ = ${g.type_sidx(got)}') + sb.write_string('\treturn ($exp_cname){ ._$got_cname = ptr, ._typ = $type_idx') for field in (exp_sym.info as ast.SumType).fields { mut ptr := 'ptr' mut type_cname := got_cname diff --git a/vlib/v/tests/inout/sumtype_with_fntype.out b/vlib/v/tests/inout/sumtype_with_fntype.out index 7075abf4a..719dfb043 100644 --- a/vlib/v/tests/inout/sumtype_with_fntype.out +++ b/vlib/v/tests/inout/sumtype_with_fntype.out @@ -1,2 +1,6 @@ -Fn -Fn +Fn(fn () int) +Fn(fn (int) int) +123 +123 +321 +321 diff --git a/vlib/v/tests/inout/sumtype_with_fntype.vv b/vlib/v/tests/inout/sumtype_with_fntype.vv index f737eb16c..116fc29c7 100644 --- a/vlib/v/tests/inout/sumtype_with_fntype.vv +++ b/vlib/v/tests/inout/sumtype_with_fntype.vv @@ -1,13 +1,32 @@ type Fn = fn () int | fn (int) int +fn abc(n int) Fn { + if n == 1 { + return fn () int { + return 123 + } + } else { + return fn (x int) int { + return x + } + } +} + fn main() { - f1 := Fn(fn (a int) int { - return a - }) - println(typeof(f1).name) - - f2 := Fn(fn () int { - return 22 - }) - println(typeof(f2).name) + println(abc(1)) + println(abc(2)) + + x1 := abc(1) + y1 := x1 as fn () int + println(y1()) + if x1 is fn () int { + println(x1()) + } + + x2 := abc(2) + y2 := x2 as fn (int) int + println(y2(321)) + if x2 is fn (int) int { + println(x2(321)) + } } -- 2.30.2