mirror of
https://github.com/vlang/v.git
synced 2025-09-13 22:42:26 +03:00
checker: allow for each(a, |x| println(x))
, i.e. using lambda expressions, when expecting fn (x int)
This commit is contained in:
parent
b81a5325ef
commit
e115d4461c
2 changed files with 55 additions and 6 deletions
|
@ -33,3 +33,17 @@ fn test_all() {
|
|||
assert !a.all(|x| x > 4)
|
||||
assert a.all(|x| x < 40)
|
||||
}
|
||||
|
||||
fn each(a []int, cb fn (x int)) {
|
||||
for x in a {
|
||||
cb(x)
|
||||
}
|
||||
}
|
||||
|
||||
fn test_using_lambda_expr_that_does_not_return_as_cb() {
|
||||
each(a, fn (x int) {
|
||||
println(x)
|
||||
})
|
||||
each(a, |x| println(x))
|
||||
each(a, |x| dump(x))
|
||||
}
|
||||
|
|
|
@ -24,11 +24,15 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
|
|||
return ast.void_type
|
||||
}
|
||||
mut params := []ast.Param{}
|
||||
mut generic_types := map[ast.Type]bool{}
|
||||
for idx, mut x in node.params {
|
||||
eparam := exp_sym.info.func.params[idx]
|
||||
eparam_type := eparam.typ
|
||||
eparam_auto_deref := eparam.typ.is_ptr()
|
||||
c.lambda_expr_fix_type_of_param(mut node, mut x, eparam_type)
|
||||
if eparam_type.has_flag(.generic) {
|
||||
generic_types[eparam_type] = true
|
||||
}
|
||||
params << ast.Param{
|
||||
pos: x.pos
|
||||
name: x.name
|
||||
|
@ -37,16 +41,42 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
|
|||
is_auto_rec: eparam_auto_deref
|
||||
}
|
||||
}
|
||||
/////
|
||||
|
||||
is_variadic := false
|
||||
return_type := exp_sym.info.func.return_type
|
||||
return_type_pos := node.pos
|
||||
mut stmts := []ast.Stmt{}
|
||||
mut return_stmt := ast.Return{
|
||||
pos: node.pos
|
||||
exprs: [node.expr]
|
||||
if return_type.has_flag(.generic) {
|
||||
generic_types[return_type] = true
|
||||
}
|
||||
|
||||
mut generic_names := []string{}
|
||||
for t, _ in generic_types {
|
||||
gtnames := c.table.generic_type_names(t)
|
||||
for x in gtnames {
|
||||
if x !in generic_names {
|
||||
generic_names << x
|
||||
}
|
||||
}
|
||||
}
|
||||
// dump(generic_types)
|
||||
// dump(generic_names)
|
||||
|
||||
mut stmts := []ast.Stmt{}
|
||||
mut has_return := false
|
||||
if return_type == ast.void_type {
|
||||
stmts << ast.ExprStmt{
|
||||
pos: node.pos
|
||||
expr: node.expr
|
||||
is_expr: false
|
||||
typ: return_type
|
||||
}
|
||||
} else {
|
||||
stmts << ast.Return{
|
||||
pos: node.pos
|
||||
exprs: [node.expr]
|
||||
}
|
||||
has_return = true
|
||||
}
|
||||
stmts << return_stmt
|
||||
|
||||
mut func := ast.Fn{
|
||||
params: params
|
||||
|
@ -64,6 +94,7 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
|
|||
short_name: ''
|
||||
mod: c.file.mod.name
|
||||
stmts: stmts
|
||||
has_return: has_return
|
||||
return_type: return_type
|
||||
return_type_pos: return_type_pos
|
||||
params: params
|
||||
|
@ -74,9 +105,13 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
|
|||
pos: node.pos.extend(node.pos_end)
|
||||
file: c.file.path
|
||||
scope: node.scope.parent
|
||||
generic_names: generic_names
|
||||
}
|
||||
typ: typ
|
||||
}
|
||||
if node.func.decl.generic_names.len > 0 {
|
||||
c.table.register_fn_generic_types(node.func.decl.fkey())
|
||||
}
|
||||
c.anon_fn(mut node.func)
|
||||
}
|
||||
node.is_checked = true
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue