mirror of
https://github.com/vlang/v.git
synced 2025-09-13 14:32:26 +03:00
This commit is contained in:
parent
9e1273ae71
commit
1ba45123ec
4 changed files with 61 additions and 17 deletions
|
@ -1472,6 +1472,7 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
|
||||||
node.pos)
|
node.pos)
|
||||||
}
|
}
|
||||||
mut has_decompose := false
|
mut has_decompose := false
|
||||||
|
mut nr_multi_values := 0
|
||||||
for i, mut call_arg in node.args {
|
for i, mut call_arg in node.args {
|
||||||
if func.params.len == 0 {
|
if func.params.len == 0 {
|
||||||
continue
|
continue
|
||||||
|
@ -1482,21 +1483,22 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
|
||||||
if !func.is_variadic && has_decompose {
|
if !func.is_variadic && has_decompose {
|
||||||
c.error('cannot have parameter after array decompose', node.pos)
|
c.error('cannot have parameter after array decompose', node.pos)
|
||||||
}
|
}
|
||||||
|
param_i := i + nr_multi_values
|
||||||
param := if func.is_variadic && i >= func.params.len - 1 {
|
param := if func.is_variadic && i >= func.params.len - 1 {
|
||||||
func.params.last()
|
func.params.last()
|
||||||
} else {
|
} else {
|
||||||
func.params[i]
|
func.params[param_i]
|
||||||
}
|
}
|
||||||
// registers if the arg must be passed by ref to disable auto deref args
|
// registers if the arg must be passed by ref to disable auto deref args
|
||||||
call_arg.should_be_ptr = param.typ.is_ptr() && !param.is_mut
|
call_arg.should_be_ptr = param.typ.is_ptr() && !param.is_mut
|
||||||
if func.is_variadic && call_arg.expr is ast.ArrayDecompose {
|
if func.is_variadic && call_arg.expr is ast.ArrayDecompose {
|
||||||
if i > func.params.len - 1 {
|
if param_i > func.params.len - 1 {
|
||||||
c.error('too many arguments in call to `${func.name}`', node.pos)
|
c.error('too many arguments in call to `${func.name}`', node.pos)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
has_decompose = call_arg.expr is ast.ArrayDecompose
|
has_decompose = call_arg.expr is ast.ArrayDecompose
|
||||||
already_checked := node.language != .js && call_arg.expr is ast.CallExpr
|
already_checked := node.language != .js && call_arg.expr is ast.CallExpr
|
||||||
if func.is_variadic && i >= func.params.len - 1 {
|
if func.is_variadic && param_i >= func.params.len - 1 {
|
||||||
param_sym := c.table.sym(param.typ)
|
param_sym := c.table.sym(param.typ)
|
||||||
mut expected_type := param.typ
|
mut expected_type := param.typ
|
||||||
if param_sym.info is ast.Array {
|
if param_sym.info is ast.Array {
|
||||||
|
@ -1688,15 +1690,16 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
|
||||||
multi_param := if func.is_variadic && i >= func.params.len - 1 {
|
multi_param := if func.is_variadic && i >= func.params.len - 1 {
|
||||||
func.params.last()
|
func.params.last()
|
||||||
} else {
|
} else {
|
||||||
func.params[n + i]
|
func.params[n + param_i]
|
||||||
}
|
}
|
||||||
c.check_expected_call_arg(curr_arg, c.unwrap_generic(multi_param.typ),
|
c.check_expected_call_arg(curr_arg, c.unwrap_generic(multi_param.typ),
|
||||||
node.language, call_arg) or {
|
node.language, call_arg) or {
|
||||||
c.error('${err.msg()} in argument ${i + n + 1} to `${fn_name}` from ${c.table.type_to_str(arg_typ)}',
|
c.error('${err.msg()} in argument ${param_i + n + 1} to `${fn_name}` from ${c.table.type_to_str(arg_typ)}',
|
||||||
call_arg.pos)
|
call_arg.pos)
|
||||||
continue out
|
continue out
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
nr_multi_values += arg_typ_sym.info.types.len - 1
|
||||||
continue
|
continue
|
||||||
} else if param_typ_sym.info is ast.Struct && arg_typ_sym.info is ast.Struct
|
} else if param_typ_sym.info is ast.Struct && arg_typ_sym.info is ast.Struct
|
||||||
&& param_typ_sym.info.is_anon {
|
&& param_typ_sym.info.is_anon {
|
||||||
|
@ -1788,13 +1791,14 @@ fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) ast.
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
c.error('${err.msg()} in argument ${i + 1} to `${fn_name}`', call_arg.pos)
|
c.error('${err.msg()} in argument ${i + nr_multi_values + 1} to `${fn_name}`',
|
||||||
|
call_arg.pos)
|
||||||
}
|
}
|
||||||
if final_param_sym.kind == .struct && arg_typ !in [ast.voidptr_type, ast.nil_type]
|
if final_param_sym.kind == .struct && arg_typ !in [ast.voidptr_type, ast.nil_type]
|
||||||
&& !c.check_multiple_ptr_match(arg_typ, param.typ, param, call_arg) {
|
&& !c.check_multiple_ptr_match(arg_typ, param.typ, param, call_arg) {
|
||||||
got_typ_str, expected_typ_str := c.get_string_names_of(arg_typ, param.typ)
|
got_typ_str, expected_typ_str := c.get_string_names_of(arg_typ, param.typ)
|
||||||
c.error('cannot use `${got_typ_str}` as `${expected_typ_str}` in argument ${i + 1} to `${fn_name}`',
|
c.error('cannot use `${got_typ_str}` as `${expected_typ_str}` in argument ${i +
|
||||||
call_arg.pos)
|
nr_multi_values + 1} to `${fn_name}`', call_arg.pos)
|
||||||
}
|
}
|
||||||
// Warn about automatic (de)referencing, which will be removed soon.
|
// Warn about automatic (de)referencing, which will be removed soon.
|
||||||
if func.language != .c && !c.inside_unsafe && !(call_arg.is_mut && param.is_mut) {
|
if func.language != .c && !c.inside_unsafe && !(call_arg.is_mut && param.is_mut) {
|
||||||
|
@ -2924,6 +2928,17 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) !
|
||||||
return error('')
|
return error('')
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
} else if node.args.len > 1 && node.args.any(it.expr is ast.CallExpr
|
||||||
|
&& it.expr.nr_ret_values > 1) {
|
||||||
|
mut check_args := 0
|
||||||
|
for arg in node.args {
|
||||||
|
if arg.expr is ast.CallExpr && arg.expr.nr_ret_values > 0 {
|
||||||
|
check_args += arg.expr.nr_ret_values
|
||||||
|
} else {
|
||||||
|
check_args += 1
|
||||||
|
}
|
||||||
|
}
|
||||||
|
nr_args = check_args
|
||||||
}
|
}
|
||||||
if min_required_params < 0 {
|
if min_required_params < 0 {
|
||||||
min_required_params = 0
|
min_required_params = 0
|
||||||
|
@ -2966,7 +2981,7 @@ fn (mut c Checker) check_expected_arg_count(mut node ast.CallExpr, f &ast.Fn) !
|
||||||
)
|
)
|
||||||
return error('')
|
return error('')
|
||||||
} else if !f.is_variadic && nr_args > nr_params {
|
} else if !f.is_variadic && nr_args > nr_params {
|
||||||
unexpected_args_pos := node.args[min_required_params].pos.extend(node.args.last().pos)
|
unexpected_args_pos := node.args[int_min(min_required_params, node.args.len - 1)].pos.extend(node.args.last().pos)
|
||||||
// c.error('3expected ${min_required_params} arguments, but got ${nr_args}', unexpected_args_pos)
|
// c.error('3expected ${min_required_params} arguments, but got ${nr_args}', unexpected_args_pos)
|
||||||
c.fn_call_error_have_want(
|
c.fn_call_error_have_want(
|
||||||
nr_params: min_required_params
|
nr_params: min_required_params
|
||||||
|
|
18
vlib/v/checker/tests/multi_return_arg_missing_err.out
Normal file
18
vlib/v/checker/tests/multi_return_arg_missing_err.out
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
vlib/v/checker/tests/multi_return_arg_missing_err.vv:12:14: error: expected 2 arguments, but got 3
|
||||||
|
10 |
|
||||||
|
11 | fn main() {
|
||||||
|
12 | expect_2(1, returning_2())
|
||||||
|
| ~~~~~~~~~~~~~
|
||||||
|
13 | expect_2(returning_2(), 1)
|
||||||
|
14 | expect_4(returning_2(), returning_2())
|
||||||
|
Details: have (int literal, (int, int))
|
||||||
|
want (int, int)
|
||||||
|
vlib/v/checker/tests/multi_return_arg_missing_err.vv:13:26: error: expected 2 arguments, but got 3
|
||||||
|
11 | fn main() {
|
||||||
|
12 | expect_2(1, returning_2())
|
||||||
|
13 | expect_2(returning_2(), 1)
|
||||||
|
| ^
|
||||||
|
14 | expect_4(returning_2(), returning_2())
|
||||||
|
15 | }
|
||||||
|
Details: have ((int, int), int literal)
|
||||||
|
want (int, int)
|
15
vlib/v/checker/tests/multi_return_arg_missing_err.vv
Normal file
15
vlib/v/checker/tests/multi_return_arg_missing_err.vv
Normal file
|
@ -0,0 +1,15 @@
|
||||||
|
fn expect_2(a int, b int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn expect_4(a int, b int, c int, d int) {
|
||||||
|
}
|
||||||
|
|
||||||
|
fn returning_2() (int, int) {
|
||||||
|
return 1, 1
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
expect_2(1, returning_2())
|
||||||
|
expect_2(returning_2(), 1)
|
||||||
|
expect_4(returning_2(), returning_2())
|
||||||
|
}
|
|
@ -5,24 +5,20 @@ vlib/v/checker/tests/multi_return_err.vv:18:10: error: cannot use `f64` as `int`
|
||||||
| ~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
19 | my_func3(my_func2(), 'foo')
|
19 | my_func3(my_func2(), 'foo')
|
||||||
20 | my_func4('foo', my_func2())
|
20 | my_func4('foo', my_func2())
|
||||||
vlib/v/checker/tests/multi_return_err.vv:19:2: error: expected 3 arguments, but got 2
|
vlib/v/checker/tests/multi_return_err.vv:19:11: error: cannot use `f64` as `int` in argument 2 to `my_func3` from (int, f64)
|
||||||
17 | fn main() {
|
17 | fn main() {
|
||||||
18 | my_func(my_func2())
|
18 | my_func(my_func2())
|
||||||
19 | my_func3(my_func2(), 'foo')
|
19 | my_func3(my_func2(), 'foo')
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
20 | my_func4('foo', my_func2())
|
20 | my_func4('foo', my_func2())
|
||||||
21 | my_func(my_func5())
|
21 | my_func(my_func5())
|
||||||
Details: have ((int, f64), string)
|
vlib/v/checker/tests/multi_return_err.vv:20:18: error: cannot use `f64` as `int` in argument 3 to `my_func4` from (int, f64)
|
||||||
want (int, int, string)
|
|
||||||
vlib/v/checker/tests/multi_return_err.vv:20:2: error: expected 3 arguments, but got 2
|
|
||||||
18 | my_func(my_func2())
|
18 | my_func(my_func2())
|
||||||
19 | my_func3(my_func2(), 'foo')
|
19 | my_func3(my_func2(), 'foo')
|
||||||
20 | my_func4('foo', my_func2())
|
20 | my_func4('foo', my_func2())
|
||||||
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
| ~~~~~~~~~~
|
||||||
21 | my_func(my_func5())
|
21 | my_func(my_func5())
|
||||||
22 | my_func(my_func6())
|
22 | my_func(my_func6())
|
||||||
Details: have (string, (int, f64))
|
|
||||||
want (string, int, int)
|
|
||||||
vlib/v/checker/tests/multi_return_err.vv:21:2: error: expected 2 arguments, but got 1
|
vlib/v/checker/tests/multi_return_err.vv:21:2: error: expected 2 arguments, but got 1
|
||||||
19 | my_func3(my_func2(), 'foo')
|
19 | my_func3(my_func2(), 'foo')
|
||||||
20 | my_func4('foo', my_func2())
|
20 | my_func4('foo', my_func2())
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue