checker: make optional arguments in func call an error (#9362)
parent
c8416f9a54
commit
f9bbc119aa
|
@ -1499,7 +1499,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
|||
}
|
||||
exp_arg_sym := c.table.get_type_symbol(exp_arg_typ)
|
||||
c.expected_type = exp_arg_typ
|
||||
got_arg_typ := c.expr(arg.expr)
|
||||
got_arg_typ := c.check_expr_opt_call(arg.expr, c.expr(arg.expr))
|
||||
call_expr.args[i].typ = got_arg_typ
|
||||
if method.is_variadic && got_arg_typ.has_flag(.variadic) && call_expr.args.len - 1 > i {
|
||||
c.error('when forwarding a variadic variable, it must be the final argument',
|
||||
|
@ -1634,7 +1634,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type {
|
|||
call_expr.return_type = info.func.return_type
|
||||
mut earg_types := []table.Type{}
|
||||
for mut arg in call_expr.args {
|
||||
targ := c.expr(arg.expr)
|
||||
targ := c.check_expr_opt_call(arg.expr, c.expr(arg.expr))
|
||||
arg.typ = targ
|
||||
earg_types << targ
|
||||
}
|
||||
|
@ -1732,7 +1732,7 @@ fn (mut c Checker) call_array_builtin_method(mut call_expr ast.CallExpr, left_ty
|
|||
// map/filter are supposed to have 1 arg only
|
||||
mut arg_type := left_type
|
||||
for arg in call_expr.args {
|
||||
arg_type = c.expr(arg.expr)
|
||||
arg_type = c.check_expr_opt_call(arg.expr, c.expr(arg.expr))
|
||||
}
|
||||
if method_name == 'map' {
|
||||
// check fn
|
||||
|
@ -2024,7 +2024,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type {
|
|||
}
|
||||
}
|
||||
c.expected_type = arg.typ
|
||||
typ := c.expr(call_arg.expr)
|
||||
typ := c.check_expr_opt_call(call_arg.expr, c.expr(call_arg.expr))
|
||||
call_expr.args[i].typ = typ
|
||||
typ_sym := c.table.get_type_symbol(typ)
|
||||
arg_typ_sym := c.table.get_type_symbol(arg.typ)
|
||||
|
|
|
@ -1,20 +1,104 @@
|
|||
vlib/v/checker/tests/optional_fn_err.vv:11:2: error: foo() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
9 | fn main() {
|
||||
10 | // Calling foo() without ? or an or block, should be an error.
|
||||
11 | foo()
|
||||
vlib/v/checker/tests/optional_fn_err.vv:25:2: error: foo() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
23 | fn main() {
|
||||
24 | // Calling foo() without ? or an or block, should be an error.
|
||||
25 | foo()
|
||||
| ~~~~~
|
||||
12 |
|
||||
13 | _ := bar()
|
||||
vlib/v/checker/tests/optional_fn_err.vv:13:7: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
11 | foo()
|
||||
12 |
|
||||
13 | _ := bar()
|
||||
| ~~~~~
|
||||
14 | _ := [bar()]
|
||||
15 | }
|
||||
vlib/v/checker/tests/optional_fn_err.vv:14:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
12 |
|
||||
13 | _ := bar()
|
||||
14 | _ := [bar()]
|
||||
| ~~~~~
|
||||
15 | }
|
||||
26 |
|
||||
27 | _ := bar(0)
|
||||
vlib/v/checker/tests/optional_fn_err.vv:27:7: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
25 | foo()
|
||||
26 |
|
||||
27 | _ := bar(0)
|
||||
| ~~~~~~
|
||||
28 | _ := [bar(0)]
|
||||
29 |
|
||||
vlib/v/checker/tests/optional_fn_err.vv:28:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
26 |
|
||||
27 | _ := bar(0)
|
||||
28 | _ := [bar(0)]
|
||||
| ~~~~~~
|
||||
29 |
|
||||
30 | // Calling fn with optional argument
|
||||
vlib/v/checker/tests/optional_fn_err.vv:31:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
29 |
|
||||
30 | // Calling fn with optional argument
|
||||
31 | println(twice(bar(0)))
|
||||
| ~~~~~~
|
||||
32 | // method and fn field
|
||||
33 | mut v := Data{fn (_ int) {}, 1}
|
||||
vlib/v/checker/tests/optional_fn_err.vv:34:8: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
32 | // method and fn field
|
||||
33 | mut v := Data{fn (_ int) {}, 1}
|
||||
34 | v.add(bar(0))
|
||||
| ~~~~~~
|
||||
35 | v.f(bar(0))
|
||||
36 | // anon fn
|
||||
vlib/v/checker/tests/optional_fn_err.vv:35:6: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
33 | mut v := Data{fn (_ int) {}, 1}
|
||||
34 | v.add(bar(0))
|
||||
35 | v.f(bar(0))
|
||||
| ~~~~~~
|
||||
36 | // anon fn
|
||||
37 | fn (_ int) {}(bar(0))
|
||||
vlib/v/checker/tests/optional_fn_err.vv:37:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
35 | v.f(bar(0))
|
||||
36 | // anon fn
|
||||
37 | fn (_ int) {}(bar(0))
|
||||
| ~~~~~~
|
||||
38 | // array builtin methods
|
||||
39 | mut arr := [1, 2]
|
||||
vlib/v/checker/tests/optional_fn_err.vv:40:16: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
38 | // array builtin methods
|
||||
39 | mut arr := [1, 2]
|
||||
40 | arr.insert(0, bar(0))
|
||||
| ~~~~~~
|
||||
41 | arr.prepend(bar(0))
|
||||
42 | arr.contains(bar(0))
|
||||
vlib/v/checker/tests/optional_fn_err.vv:41:14: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
39 | mut arr := [1, 2]
|
||||
40 | arr.insert(0, bar(0))
|
||||
41 | arr.prepend(bar(0))
|
||||
| ~~~~~~
|
||||
42 | arr.contains(bar(0))
|
||||
43 | arr.index(bar(0))
|
||||
vlib/v/checker/tests/optional_fn_err.vv:42:15: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
40 | arr.insert(0, bar(0))
|
||||
41 | arr.prepend(bar(0))
|
||||
42 | arr.contains(bar(0))
|
||||
| ~~~~~~
|
||||
43 | arr.index(bar(0))
|
||||
44 | println(arr.map(bar(0)))
|
||||
vlib/v/checker/tests/optional_fn_err.vv:43:12: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
41 | arr.prepend(bar(0))
|
||||
42 | arr.contains(bar(0))
|
||||
43 | arr.index(bar(0))
|
||||
| ~~~~~~
|
||||
44 | println(arr.map(bar(0)))
|
||||
45 | println(arr.filter(bar(true)))
|
||||
vlib/v/checker/tests/optional_fn_err.vv:44:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
42 | arr.contains(bar(0))
|
||||
43 | arr.index(bar(0))
|
||||
44 | println(arr.map(bar(0)))
|
||||
| ~~~~~~
|
||||
45 | println(arr.filter(bar(true)))
|
||||
46 | println(arr.any(bar(true)))
|
||||
vlib/v/checker/tests/optional_fn_err.vv:45:21: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
43 | arr.index(bar(0))
|
||||
44 | println(arr.map(bar(0)))
|
||||
45 | println(arr.filter(bar(true)))
|
||||
| ~~~~~~~~~
|
||||
46 | println(arr.any(bar(true)))
|
||||
47 | println(arr.all(bar(true)))
|
||||
vlib/v/checker/tests/optional_fn_err.vv:46:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
44 | println(arr.map(bar(0)))
|
||||
45 | println(arr.filter(bar(true)))
|
||||
46 | println(arr.any(bar(true)))
|
||||
| ~~~~~~~~~
|
||||
47 | println(arr.all(bar(true)))
|
||||
48 | }
|
||||
vlib/v/checker/tests/optional_fn_err.vv:47:18: error: bar() returns an option, so it should have either an `or {}` block, or `?` at the end
|
||||
45 | println(arr.filter(bar(true)))
|
||||
46 | println(arr.any(bar(true)))
|
||||
47 | println(arr.all(bar(true)))
|
||||
| ~~~~~~~~~
|
||||
48 | }
|
||||
|
|
|
@ -2,14 +2,47 @@ fn foo() ? {
|
|||
println('foo is called')
|
||||
}
|
||||
|
||||
fn bar() ?int {
|
||||
fn bar<T>(v T) ?T {
|
||||
return none
|
||||
}
|
||||
|
||||
struct Data {
|
||||
f fn (int)
|
||||
mut:
|
||||
value int
|
||||
}
|
||||
|
||||
fn (mut v Data) add(n int) {
|
||||
v.value += n
|
||||
}
|
||||
|
||||
fn twice(n int) int {
|
||||
return n * 2
|
||||
}
|
||||
|
||||
fn main() {
|
||||
// Calling foo() without ? or an or block, should be an error.
|
||||
foo()
|
||||
|
||||
_ := bar()
|
||||
_ := [bar()]
|
||||
_ := bar(0)
|
||||
_ := [bar(0)]
|
||||
|
||||
// Calling fn with optional argument
|
||||
println(twice(bar(0)))
|
||||
// method and fn field
|
||||
mut v := Data{fn (_ int) {}, 1}
|
||||
v.add(bar(0))
|
||||
v.f(bar(0))
|
||||
// anon fn
|
||||
fn (_ int) {}(bar(0))
|
||||
// array builtin methods
|
||||
mut arr := [1, 2]
|
||||
arr.insert(0, bar(0))
|
||||
arr.prepend(bar(0))
|
||||
arr.contains(bar(0))
|
||||
arr.index(bar(0))
|
||||
println(arr.map(bar(0)))
|
||||
println(arr.filter(bar(true)))
|
||||
println(arr.any(bar(true)))
|
||||
println(arr.all(bar(true)))
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue