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 > 4)
|
||||||
assert a.all(|x| x < 40)
|
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
|
return ast.void_type
|
||||||
}
|
}
|
||||||
mut params := []ast.Param{}
|
mut params := []ast.Param{}
|
||||||
|
mut generic_types := map[ast.Type]bool{}
|
||||||
for idx, mut x in node.params {
|
for idx, mut x in node.params {
|
||||||
eparam := exp_sym.info.func.params[idx]
|
eparam := exp_sym.info.func.params[idx]
|
||||||
eparam_type := eparam.typ
|
eparam_type := eparam.typ
|
||||||
eparam_auto_deref := eparam.typ.is_ptr()
|
eparam_auto_deref := eparam.typ.is_ptr()
|
||||||
c.lambda_expr_fix_type_of_param(mut node, mut x, eparam_type)
|
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{
|
params << ast.Param{
|
||||||
pos: x.pos
|
pos: x.pos
|
||||||
name: x.name
|
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_auto_rec: eparam_auto_deref
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/////
|
|
||||||
is_variadic := false
|
is_variadic := false
|
||||||
return_type := exp_sym.info.func.return_type
|
return_type := exp_sym.info.func.return_type
|
||||||
return_type_pos := node.pos
|
return_type_pos := node.pos
|
||||||
mut stmts := []ast.Stmt{}
|
if return_type.has_flag(.generic) {
|
||||||
mut return_stmt := ast.Return{
|
generic_types[return_type] = true
|
||||||
pos: node.pos
|
}
|
||||||
exprs: [node.expr]
|
|
||||||
|
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{
|
mut func := ast.Fn{
|
||||||
params: params
|
params: params
|
||||||
|
@ -64,6 +94,7 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
|
||||||
short_name: ''
|
short_name: ''
|
||||||
mod: c.file.mod.name
|
mod: c.file.mod.name
|
||||||
stmts: stmts
|
stmts: stmts
|
||||||
|
has_return: has_return
|
||||||
return_type: return_type
|
return_type: return_type
|
||||||
return_type_pos: return_type_pos
|
return_type_pos: return_type_pos
|
||||||
params: params
|
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)
|
pos: node.pos.extend(node.pos_end)
|
||||||
file: c.file.path
|
file: c.file.path
|
||||||
scope: node.scope.parent
|
scope: node.scope.parent
|
||||||
|
generic_names: generic_names
|
||||||
}
|
}
|
||||||
typ: typ
|
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)
|
c.anon_fn(mut node.func)
|
||||||
}
|
}
|
||||||
node.is_checked = true
|
node.is_checked = true
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue