From 60ecbec8eaa194cd7b922dbbec73d4ba1a46b3be Mon Sep 17 00:00:00 2001 From: 05st <60903484+05st@users.noreply.github.com> Date: Fri, 1 Oct 2021 08:52:34 -0500 Subject: [PATCH] cgen: fix closure code gen with if statement in definition (#12028) --- vlib/v/gen/c/fn.v | 11 ++++------- vlib/v/tests/closure_test.v | 17 +++++++++++++++++ 2 files changed, 21 insertions(+), 7 deletions(-) diff --git a/vlib/v/gen/c/fn.v b/vlib/v/gen/c/fn.v index 2cf6426e7b..9ff2b3d362 100644 --- a/vlib/v/gen/c/fn.v +++ b/vlib/v/gen/c/fn.v @@ -425,20 +425,17 @@ fn (mut g Gen) gen_anon_fn(mut node ast.AnonFn) { return } // it may be possible to optimize `memdup` out if the closure never leaves current scope - ctx_var := g.new_tmp_var() - cur_line := g.go_before_stmt(0) ctx_struct := closure_ctx_struct(node.decl) - g.writeln('$ctx_struct* $ctx_var = ($ctx_struct*) memdup(&($ctx_struct){') + // TODO in case of an assignment, this should only call "__closure_set_data" and "__closure_set_function" (and free the former data) + g.write('__closure_create($node.decl.name, ${node.decl.params.len + 1}, ') + g.writeln('($ctx_struct*) memdup(&($ctx_struct){') g.indent++ for var in node.inherited_vars { g.writeln('.$var.name = $var.name,') } g.indent-- - g.writeln('}, sizeof($ctx_struct));') + g.write('}, sizeof($ctx_struct)))') g.empty_line = false - g.write(cur_line) - // TODO in case of an assignment, this should only call "__closure_set_data" and "__closure_set_function" (and free the former data) - g.write('__closure_create($node.decl.name, ${node.decl.params.len + 1}, $ctx_var)') } fn (mut g Gen) gen_anon_fn_decl(mut node ast.AnonFn) { diff --git a/vlib/v/tests/closure_test.v b/vlib/v/tests/closure_test.v index 483f92ebab..f58e94e85d 100644 --- a/vlib/v/tests/closure_test.v +++ b/vlib/v/tests/closure_test.v @@ -151,3 +151,20 @@ fn test_go_call_closure() { assert <-ch == 15 } */ + +fn test_closures_with_ifstmt() { + a := 1 + f := fn [a] (x int) int { + if a > x { return 1 + } else { return -1 + } + } + g := fn [a] () int { + if true { + return 1 + } + return 0 + } + assert f(0) == 1 + assert g() == 1 +}