Skip to content

Commit

Permalink
parser, checker: check invalid lambda expr
Browse files Browse the repository at this point in the history
  • Loading branch information
yuyi98 committed Jan 10, 2024
1 parent 14f3c95 commit 0109bdb
Show file tree
Hide file tree
Showing 7 changed files with 36 additions and 14 deletions.
10 changes: 10 additions & 0 deletions vlib/v/checker/errors.v
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,16 @@ fn (mut c Checker) error(message string, pos token.Pos) {
c.warn_or_error(msg, pos, false)
}

fn (mut c Checker) fatal(message string, pos token.Pos) {
if (c.pref.translated || c.file.is_translated) && message.starts_with('mismatched types') {
// TODO move this
return
}
msg := message.replace('`Array_', '`[]')
c.pref.fatal_errors = true
c.warn_or_error(msg, pos, false)
}

fn (mut c Checker) note(message string, pos token.Pos) {
if c.pref.message_limit >= 0 && c.nr_notices >= c.pref.message_limit {
c.should_abort = true
Expand Down
4 changes: 2 additions & 2 deletions vlib/v/checker/lambda_expr.v
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ pub fn (mut c Checker) lambda_expr(mut node ast.LambdaExpr, exp_typ ast.Type) as
if node.is_checked {
return node.typ
}
if exp_typ == 0 {
c.error('lambda expressions are allowed only in places expecting function callbacks',
if exp_typ in [0, ast.void_type] {
c.fatal('lambda expressions are allowed only in places expecting function callbacks',
node.pos)
return ast.void_type
}
Expand Down
4 changes: 2 additions & 2 deletions vlib/v/checker/tests/lambda_expression_in_map.out
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ vlib/v/checker/tests/lambda_expression_in_map.vv:3:12: error: lambda expressions
1 | a := [4, 5]
2 | dump(a.map(it))
3 | dump(a.map(|| 5))
| ~~
| ~~~~
4 | dump(a.map(|x| 5 * x))
5 | dump(a.map(|x| x))
vlib/v/checker/tests/lambda_expression_in_map.vv:3:8: error: dump expression can not be void
Expand All @@ -16,7 +16,7 @@ vlib/v/checker/tests/lambda_expression_in_map.vv:6:12: error: lambda expressions
4 | dump(a.map(|x| 5 * x))
5 | dump(a.map(|x| x))
6 | dump(a.map(|x, y| x))
| ^
| ~~~~~~~~
vlib/v/checker/tests/lambda_expression_in_map.vv:6:8: error: dump expression can not be void
4 | dump(a.map(|x| 5 * x))
5 | dump(a.map(|x| x))
Expand Down
7 changes: 7 additions & 0 deletions vlib/v/checker/tests/lambda_expression_invalid.out
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
vlib/v/checker/tests/lambda_expression_invalid.vv:3:19: error: lambda expressions are allowed only in places expecting function callbacks
1 | fn main() {
2 | x := 5
3 | f := if x == 5 { |x| x - 5 } else { |x| x }
| ~~~~~~~~~
4 | println(f(x))
5 | }
5 changes: 5 additions & 0 deletions vlib/v/checker/tests/lambda_expression_invalid.vv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
fn main() {
x := 5
f := if x == 5 { |x| x - 5 } else { |x| x }
println(f(x))
}
18 changes: 9 additions & 9 deletions vlib/v/checker/tests/lambda_undefined_variables_err.out
Original file line number Diff line number Diff line change
@@ -1,33 +1,33 @@
vlib/v/checker/tests/lambda_undefined_variables_err.vv:7:2: warning: unused variable: `s2`
5 | f(|x| s1)
6 |
6 |
7 | s2 := 'abc'
| ~~
8 | f(|x| s2)
9 | }
vlib/v/checker/tests/lambda_undefined_variables_err.vv:5:8: error: undefined ident: `s1`
3 |
3 |
4 | fn main() {
5 | f(|x| s1)
| ~~
6 |
6 |
7 | s2 := 'abc'
vlib/v/checker/tests/lambda_undefined_variables_err.vv:5:4: error: `s1` used as value
3 |
3 |
4 | fn main() {
5 | f(|x| s1)
| ^
6 |
| ~~~~~~
6 |
7 | s2 := 'abc'
vlib/v/checker/tests/lambda_undefined_variables_err.vv:8:8: error: undefined variable `s2`
6 |
6 |
7 | s2 := 'abc'
8 | f(|x| s2)
| ~~
9 | }
vlib/v/checker/tests/lambda_undefined_variables_err.vv:8:4: error: `s2` used as value
6 |
6 |
7 | s2 := 'abc'
8 | f(|x| s2)
| ^
| ~~~~~~
9 | }
2 changes: 1 addition & 1 deletion vlib/v/parser/expr.v
Original file line number Diff line number Diff line change
Expand Up @@ -900,7 +900,7 @@ fn (mut p Parser) lambda_expr() ?ast.LambdaExpr {
e := p.expr(0)
pos_end := p.tok.pos()
return ast.LambdaExpr{
pos: pos
pos: pos.extend(e.pos())
pos_expr: pos_expr
pos_end: pos_end
params: params
Expand Down

0 comments on commit 0109bdb

Please sign in to comment.