diff --git a/vlib/v/checker/return.v b/vlib/v/checker/return.v index 805f20f9104bb8..e970f72dc9da56 100644 --- a/vlib/v/checker/return.v +++ b/vlib/v/checker/return.v @@ -267,11 +267,6 @@ fn (mut c Checker) return_stmt(mut node ast.Return) { if c.inside_lambda && exp_type.has_flag(.generic) { continue } - // ignore return closure - if node.exprs[expr_idxs[i]] is ast.AnonFn - && node.exprs[expr_idxs[i]].inherited_vars.len > 0 { - continue - } c.error('cannot use `${got_type_name}` as ${c.error_type_name(exp_type)} in return argument', pos) } diff --git a/vlib/v/checker/tests/generics_fn_return_generic_closure_err.out b/vlib/v/checker/tests/generics_fn_return_generic_closure_err.out new file mode 100644 index 00000000000000..568c1f6f0bf180 --- /dev/null +++ b/vlib/v/checker/tests/generics_fn_return_generic_closure_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/generics_fn_return_generic_closure_err.vv:2:9: error: cannot use `fn (f64) []f64` as type `fn ([]f64) []f64` in return argument + 1 | fn vectorize[T](op fn (T) T) fn ([]T) []T { + 2 | return fn [op] [T](values T) []T { + | ~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 3 | mut result := []T{} + 4 | return result diff --git a/vlib/v/checker/tests/generics_fn_return_generic_closure_err.vv b/vlib/v/checker/tests/generics_fn_return_generic_closure_err.vv new file mode 100644 index 00000000000000..5c321b72c3ed38 --- /dev/null +++ b/vlib/v/checker/tests/generics_fn_return_generic_closure_err.vv @@ -0,0 +1,16 @@ +fn vectorize[T](op fn (T) T) fn ([]T) []T { + return fn [op] [T](values T) []T { + mut result := []T{} + return result + } +} + +fn add_one(x f64) f64 { + return x + 1 +} + +fn main() { + vadd := vectorize[f64](add_one) + v := [1.0, 2, 3, 4] + println(vadd(v)) +} diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 146291971257fb..907ff65e62444b 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -889,7 +889,7 @@ fn (mut p Parser) anon_fn() ast.AnonFn { p.cur_fn_name = keep_fn_name func.name = name idx := p.table.find_or_register_fn_type(func, true, false) - typ := ast.new_type(idx) + typ := if generic_names.len > 0 { ast.new_type(idx).set_flag(.generic) } else { ast.new_type(idx) } p.inside_defer = old_inside_defer // name := p.table.get_type_name(typ) return ast.AnonFn{ diff --git a/vlib/v/tests/generics/generics_return_closure_test.v b/vlib/v/tests/generics/generics_return_closure_test.v index 07a2f2791a5cfb..1e6d2e1d77e993 100644 --- a/vlib/v/tests/generics/generics_return_closure_test.v +++ b/vlib/v/tests/generics/generics_return_closure_test.v @@ -8,12 +8,22 @@ fn vectorize[T](op fn (T) T) fn ([]T) []T { } } -fn add_one(x f64) f64 { +fn add_one1(x f64) f64 { return x + 1 } -fn test_return_generic_closure() { - vadd := vectorize[f64](add_one) - v := [1.0, 2, 3, 4] - assert vadd(v) == [2.0, 3, 4, 5] +fn add_one2(x int) int { + return x + 1 +} + +fn test_generic_return_generic_closure() { + vadd1 := vectorize[f64](add_one1) + v1 := [1.0, 2, 3, 4] + println(vadd1(v1)) + assert vadd1(v1) == [2.0, 3, 4, 5] + + vadd2 := vectorize[int](add_one2) + v2 := [1, 2, 3, 4] + println(vadd2(v2)) + assert vadd2(v2) == [2, 3, 4, 5] }