diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 1bdadcff4c..36ac24d7d8 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1235,11 +1235,12 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { min_required_args := method.params.len - if method.is_variadic && method.params.len > 1 { 2 } else { 1 } if call_expr.args.len < min_required_args { - c.error('too few arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $min_required_args)', + c.error('expected $min_required_args arguments, but got $call_expr.args.len', call_expr.pos) } else if !method.is_variadic && call_expr.args.len > nr_args { - c.error('too many arguments in call to `${left_type_sym.name}.$method_name` ($call_expr.args.len instead of $nr_args)', - call_expr.pos) + unexpected_arguments := call_expr.args[min_required_args..] + unexpected_arguments_pos := unexpected_arguments[0].pos.extend(unexpected_arguments.last().pos) + c.error('expected $nr_args arguments, but got $call_expr.args.len', unexpected_arguments_pos) return method.return_type } // if method_name == 'clone' { @@ -1511,11 +1512,13 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { } min_required_args := if f.is_variadic { f.params.len - 1 } else { f.params.len } if call_expr.args.len < min_required_args { - c.error('too few arguments in call to `$fn_name` ($call_expr.args.len instead of $min_required_args)', + c.error('expected $min_required_args arguments, but got $call_expr.args.len', call_expr.pos) } else if !f.is_variadic && call_expr.args.len > f.params.len { - c.error('too many arguments in call to `$fn_name` ($call_expr.args.len instead of $f.params.len)', - call_expr.pos) + unexpected_arguments := call_expr.args[min_required_args..] + unexpected_arguments_pos := unexpected_arguments[0].pos.extend(unexpected_arguments.last().pos) + c.error('expected $min_required_args arguments, but got $call_expr.args.len', + unexpected_arguments_pos) return f.return_type } // println can print anything diff --git a/vlib/v/checker/tests/fn_args.out b/vlib/v/checker/tests/fn_args.out index fbd345e5d2..904eb3483f 100644 --- a/vlib/v/checker/tests/fn_args.out +++ b/vlib/v/checker/tests/fn_args.out @@ -1,19 +1,19 @@ -vlib/v/checker/tests/fn_args.vv:6:7: error: invalid argument 1 to `ptr`: expected `byte`, not `&int` - 4 | +vlib/v/checker/tests/fn_args.vv:6:5: error: invalid argument 1 to `ptr`: expected `byte`, not `&int` + 4 | 5 | v := 4 6 | ptr(&v) - | ^ + | ~~ 7 | arr([5]!!) 8 | fun(fn(i &int){}) -vlib/v/checker/tests/fn_args.vv:7:10: error: invalid argument 1 to `arr`: expected `[]int`, not `[1]int` +vlib/v/checker/tests/fn_args.vv:7:5: error: invalid argument 1 to `arr`: expected `[]int`, not `[1]int` 5 | v := 4 6 | ptr(&v) 7 | arr([5]!!) - | ^ + | ~~~~~ 8 | fun(fn(i &int){}) -vlib/v/checker/tests/fn_args.vv:8:17: error: invalid argument 1 to `fun`: expected `fn (int)`, not `fn (&int)` +vlib/v/checker/tests/fn_args.vv:8:5: error: invalid argument 1 to `fun`: expected `fn (int)`, not `fn (&int)` 6 | ptr(&v) 7 | arr([5]!!) 8 | fun(fn(i &int){}) - | ^ -details: ``'s expected fn argument: `` is NOT a pointer, but the passed fn argument: `i` is a pointer + | ~~~~~~~~~~~~ +details: ``'s expected fn argument: `` is NOT a pointer, but the passed fn argument: `i` is a pointer \ No newline at end of file diff --git a/vlib/v/checker/tests/function_too_many_args_err.out b/vlib/v/checker/tests/function_too_many_args_err.out new file mode 100644 index 0000000000..3836d7542a --- /dev/null +++ b/vlib/v/checker/tests/function_too_many_args_err.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/function_too_many_args_err.vv:5:16: error: expected 1 arguments, but got 3 + 3 | + 4 | fn main() { + 5 | test(true, false, 1) + | ~~~~~~~~ + 6 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/function_too_many_args_err.vv b/vlib/v/checker/tests/function_too_many_args_err.vv new file mode 100644 index 0000000000..ff9759bd97 --- /dev/null +++ b/vlib/v/checker/tests/function_too_many_args_err.vv @@ -0,0 +1,6 @@ +fn test(b bool) { +} + +fn main() { + test(true, false, 1) +} diff --git a/vlib/v/checker/tests/function_wrong_arg_type.out b/vlib/v/checker/tests/function_wrong_arg_type.out index cd6e0f3d07..2e8af639cc 100644 --- a/vlib/v/checker/tests/function_wrong_arg_type.out +++ b/vlib/v/checker/tests/function_wrong_arg_type.out @@ -1,7 +1,7 @@ -vlib/v/checker/tests/function_wrong_arg_type.vv:7:10: error: invalid argument 1 to `f`: expected `int`, not `f64` +vlib/v/checker/tests/function_wrong_arg_type.vv:7:9: error: invalid argument 1 to `f`: expected `int`, not `f64` 5 | fn main() { 6 | a := 12.3 7 | q := f(a) - | ^ + | ^ 8 | println('$q') - 9 | } + 9 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/is_type_not_exist.out b/vlib/v/checker/tests/is_type_not_exist.out index 96ce48a3c6..84c7c0c2ec 100644 --- a/vlib/v/checker/tests/is_type_not_exist.out +++ b/vlib/v/checker/tests/is_type_not_exist.out @@ -1,14 +1,14 @@ -vlib/v/checker/tests/is_type_not_exist.vv:4:26: error: invalid argument 1 to `fn_with_sum_type_param`: expected `Integer`, not `any_int` - 2 | +vlib/v/checker/tests/is_type_not_exist.vv:4:25: error: invalid argument 1 to `fn_with_sum_type_param`: expected `Integer`, not `any_int` + 2 | 3 | fn main() { 4 | fn_with_sum_type_param(1) - | ^ + | ^ 5 | } 6 | vlib/v/checker/tests/is_type_not_exist.vv:8:10: error: is: type `SomethingThatDontExist` does not exist - 6 | + 6 | 7 | fn fn_with_sum_type_param(i Integer) { 8 | if i is SomethingThatDontExist { | ~~~~~~~~~~~~~~~~~~~~~~ 9 | println('It should fail !') - 10 | } + 10 | } \ No newline at end of file diff --git a/vlib/v/checker/tests/no_main_println_err.out b/vlib/v/checker/tests/no_main_println_err.out index 495fd57634..5b0d71ef8d 100644 --- a/vlib/v/checker/tests/no_main_println_err.out +++ b/vlib/v/checker/tests/no_main_println_err.out @@ -1,3 +1,3 @@ -vlib/v/checker/tests/no_main_println_err.vv:1:5: error: too few arguments in call to `println` (0 instead of 1) +vlib/v/checker/tests/no_main_println_err.vv:1:5: error: expected 1 arguments, but got 0 1 | println() - | ~~~~~~~~~ + | ~~~~~~~~~ \ No newline at end of file diff --git a/vlib/v/checker/tests/non_matching_functional_args.out b/vlib/v/checker/tests/non_matching_functional_args.out index 472ae5ee68..2247b78129 100644 --- a/vlib/v/checker/tests/non_matching_functional_args.out +++ b/vlib/v/checker/tests/non_matching_functional_args.out @@ -1,16 +1,16 @@ -vlib/v/checker/tests/non_matching_functional_args.vv:30:3: error: invalid argument 1 to `sum`: expected `fn (Table)`, not `fn (mut Table)` +vlib/v/checker/tests/non_matching_functional_args.vv:27:6: error: invalid argument 1 to `sum`: expected `fn (Table)`, not `fn (mut Table)` + 25 | + 26 | fn main() { + 27 | sum(fn (mut t Table) { + | ~~~~~~~~~~~~~~~~~~ 28 | t.rename() 29 | println(t.name) - 30 | }) - | ^ - 31 | sum(xxx) - 32 | sum(yyy) details: `main.MyFn`'s expected fn argument: `zzzz` is NOT a pointer, but the passed fn argument: `t` is a pointer -vlib/v/checker/tests/non_matching_functional_args.vv:31:9: error: invalid argument 1 to `sum`: expected `fn (Table)`, not `fn (mut Table)` +vlib/v/checker/tests/non_matching_functional_args.vv:31:6: error: invalid argument 1 to `sum`: expected `fn (Table)`, not `fn (mut Table)` 29 | println(t.name) 30 | }) 31 | sum(xxx) - | ^ + | ~~~ 32 | sum(yyy) 33 | } -details: `main.MyFn`'s expected fn argument: `zzzz` is NOT a pointer, but the passed fn argument: `mytable` is a pointer +details: `main.MyFn`'s expected fn argument: `zzzz` is NOT a pointer, but the passed fn argument: `mytable` is a pointer \ No newline at end of file diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 935d1bfffb..144c21ca1d 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -119,14 +119,16 @@ pub fn (mut p Parser) call_args() []ast.CallArg { p.next() } mut comments := p.eat_comments() + arg_start_pos := p.tok.position() e := p.expr(0) + pos := arg_start_pos.extend(p.prev_tok.position()) comments << p.eat_comments() args << ast.CallArg{ is_mut: is_mut share: table.sharetype_from_flags(is_shared, is_atomic) expr: e comments: comments - pos: p.tok.position() + pos: pos } if p.tok.kind != .rpar { p.check(.comma)