From f0a23c8d3c3f03ac582e76cd9763352d92b762bb Mon Sep 17 00:00:00 2001 From: yuyi Date: Thu, 24 Nov 2022 18:05:57 +0800 Subject: [PATCH] cgen: fix fn call of sumtype with alias fntype variant (#16519) --- vlib/v/gen/c/cgen.v | 32 +++++++++---------- vlib/v/gen/c/fn.v | 7 ++-- vlib/v/tests/sumtype_with_alias_fntype_test.v | 21 ++++++++---- 3 files changed, 33 insertions(+), 27 deletions(-) diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index 9f6d9c75ac..b1a495cb09 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -2281,25 +2281,23 @@ fn (mut g Gen) write_sumtype_casting_fn(fun SumtypeCastingFn) { mut sb := strings.new_builder(128) mut is_anon_fn := false if got_sym.info is ast.FnType { - if got_sym.info.is_anon || g.table.known_fn(got_sym.name) { - 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 - } + 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 } + sb.writeln('static inline ${exp_cname} ${fun.fn_name}(${got_cname} x) {') + sb.writeln('\t${got_cname} ptr = x;') + is_anon_fn = true } if !is_anon_fn { sb.writeln('static inline ${exp_cname} ${fun.fn_name}(${got_cname}* x) {') @@ -2436,8 +2434,8 @@ fn (mut g Gen) expr_with_cast(expr ast.Expr, got_type_raw ast.Type, expected_typ if got_sym.info is ast.FnType { if got_sym.info.is_anon { got_styp = 'anon_fn_${g.table.fn_type_signature(got_sym.info.func)}' - got_is_fn = true } + got_is_fn = true } if expected_type != ast.void_type { unwrapped_expected_type := g.unwrap_generic(expected_type) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 6d6a6e43eb..13756bf3d8 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -1452,8 +1452,9 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { } } if obj.smartcasts.len > 0 && is_cast_needed { - for _ in obj.smartcasts { - g.write('(*') + for typ in obj.smartcasts { + sym := g.table.sym(typ) + g.write('(*(${sym.cname})(') } for i, typ in obj.smartcasts { cast_sym := g.table.sym(g.unwrap_generic(typ)) @@ -1471,7 +1472,7 @@ fn (mut g Gen) fn_call(node ast.CallExpr) { } else { g.write('${dot}_${cast_sym.cname}') } - g.write(')') + g.write('))') } is_fn_var = true } else if obj.is_inherited { diff --git a/vlib/v/tests/sumtype_with_alias_fntype_test.v b/vlib/v/tests/sumtype_with_alias_fntype_test.v index 416b5112b8..8136be6e4b 100644 --- a/vlib/v/tests/sumtype_with_alias_fntype_test.v +++ b/vlib/v/tests/sumtype_with_alias_fntype_test.v @@ -11,18 +11,25 @@ fn abc(i int) int { return i } +// create Myfn +fn myfnfact() Myfn { + return abc +} + +// run fn if exists fn run(mmff Maybefnfact) string { match mmff { - Myfnfact { return 'yes fn' } - None { return 'None fn' } + Myfnfact { + r := mmff() + return 'yes fn: ${r}' + } + 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 @@ -33,5 +40,5 @@ fn test_sumtype_with_alias_fntype() { r3 := run(myfnfact) println(r3) - assert r3 == 'yes fn' + assert r3 == 'yes fn: fn (int) int' }