1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: add checks for .map(opt_fn_name) and .filter(opt_fn_name) (#15687)

This commit is contained in:
Swastik Baranwal 2022-09-09 14:54:57 +05:30 committed by GitHub
parent 0f3a395ca2
commit 6db5781d53
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 67 additions and 0 deletions

View File

@ -1833,6 +1833,10 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, node ast
arg_expr := node.args[0].expr
match arg_expr {
ast.AnonFn {
if arg_expr.decl.return_type.has_flag(.optional) {
c.error('optional needs to be unwrapped before using it in map/filter',
node.args[0].pos)
}
if arg_expr.decl.params.len > 1 {
c.error('function needs exactly 1 argument', arg_expr.decl.pos)
} else if is_map && (arg_expr.decl.return_type == ast.void_type
@ -1850,6 +1854,10 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, node ast
c.error('$arg_expr.name does not exist', arg_expr.pos)
return
}
if func.return_type.has_flag(.optional) {
c.error('optional needs to be unwrapped before using it in map/filter',
node.pos)
}
if func.params.len > 1 {
c.error('function needs exactly 1 argument', node.pos)
} else if is_map
@ -1866,6 +1874,10 @@ fn (mut c Checker) check_map_and_filter(is_map bool, elem_typ ast.Type, node ast
expr := arg_expr.obj.expr
if expr is ast.AnonFn {
// copied from above
if expr.decl.return_type.has_flag(.optional) {
c.error('optional needs to be unwrapped before using it in map/filter',
arg_expr.pos)
}
if expr.decl.params.len > 1 {
c.error('function needs exactly 1 argument', expr.decl.pos)
} else if is_map && (expr.decl.return_type == ast.void_type

View File

@ -0,0 +1,21 @@
vlib/v/checker/tests/array_filter_map_optional_function_err.vv:14:25: error: optional needs to be unwrapped before using it in map/filter
12 | }
13 |
14 | arr_struct2 := arr.map(optional_mapping_struct)
| ~~~~~~~~~~~~~~~~~~~~~~~
15 | println(arr_struct2)
16 |
vlib/v/checker/tests/array_filter_map_optional_function_err.vv:17:18: error: optional needs to be unwrapped before using it in map/filter
15 | println(arr_struct2)
16 |
17 | arr_int2 := arr.map(optional_mapping_int)
| ~~~~~~~~~~~~~~~~~~~~~~~~~
18 | println(arr_int2)
19 |
vlib/v/checker/tests/array_filter_map_optional_function_err.vv:20:20: error: optional needs to be unwrapped before using it in map/filter
18 | println(arr_int2)
19 |
20 | arr_filter := arr.filter(optional_mapping_int)
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~
21 | println(arr_filter)
22 | }

View File

@ -0,0 +1,34 @@
fn main() {
arr := [1, 2, 3, 4, 5]
optional_mapping_struct := fn (n int) ?MyStruct {
if n < 0 {
return none
} else {
return MyStruct{
my_field: n
}
}
}
arr_struct2 := arr.map(optional_mapping_struct)
println(arr_struct2)
arr_int2 := arr.map(optional_mapping_int)
println(arr_int2)
arr_filter := arr.filter(optional_mapping_int)
println(arr_filter)
}
struct MyStruct {
my_field int
}
fn optional_mapping_int(n int) ?int {
if n < 0 {
return none
} else {
return n
}
}