From 8b5c75c4817837b144401ad75399486289631dc5 Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 24 Nov 2022 00:46:58 +0800 Subject: [PATCH] cgen: fix sumtype with alias fntype variant (#16516) --- vlib/v/gen/c/cgen.v | 11 ++++++ vlib/v/tests/sumtype_with_alias_fntype_test.v | 37 +++++++++++++++++++ 2 files changed, 48 insertions(+) create mode 100644 vlib/v/tests/sumtype_with_alias_fntype_test.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 0317828705..9f6d9c75ac 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2285,6 +2285,17 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) { 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() + exp_info := exp_sym.info as ast.SumType + for variant in exp_info.variants { + variant_sym := g.table.sym(variant) + if variant_sym.info is ast.FnType { + if g.table.fn_type_source_signature(variant_sym.info.func) == g.table.fn_type_source_signature(got_sym.info.func) { + got_cname = variant_sym.cname + type_idx = variant.idx().str() + break + } + } + } sb.writeln('static inline ${exp_cname} ${fun.fn_name}(${got_cname} x) {') sb.writeln('\t${got_cname} ptr = x;') is_anon_fn = true diff --git a/vlib/v/tests/sumtype_with_alias_fntype_test.v b/vlib/v/tests/sumtype_with_alias_fntype_test.v new file mode 100644 index 0000000000..416b5112b8 --- /dev/null +++ b/vlib/v/tests/sumtype_with_alias_fntype_test.v @@ -0,0 +1,37 @@ +struct None {} + +type Myfn = fn (int) int + +type Myfnfact = fn () Myfn + +type Maybefnfact = Myfnfact | None + +// Myfn +fn abc(i int) int { + return i +} + +fn run(mmff Maybefnfact) string { + match mmff { + Myfnfact { return 'yes fn' } + None { return 'None fn' } + } +} + +fn test_sumtype_with_alias_fntype() { + // create Myfn + myfnfact := fn () Myfn { + return abc + } + r1 := main.myfnfact()(1) + println(r1) + assert r1 == 1 + + r2 := run(None{}) + println(r2) + assert r2 == 'None fn' + + r3 := run(myfnfact) + println(r3) + assert r3 == 'yes fn' +}