Skip to content

Commit

Permalink
parser, checker: fix generic fn returning generic closure
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Dec 3, 2024
1 parent 6ac1d08 commit bba2f50
Show file tree
Hide file tree
Showing 5 changed files with 38 additions and 11 deletions.
5 changes: 0 additions & 5 deletions vlib/v/checker/return.v
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -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
16 changes: 16 additions & 0 deletions vlib/v/checker/tests/generics_fn_return_generic_closure_err.vv
Original file line number Diff line number Diff line change
@@ -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))
}
2 changes: 1 addition & 1 deletion vlib/v/parser/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -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{
Expand Down
20 changes: 15 additions & 5 deletions vlib/v/tests/generics/generics_return_closure_test.v
Original file line number Diff line number Diff line change
Expand Up @@ -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]
}

0 comments on commit bba2f50

Please sign in to comment.