From baf2ff1a91e8a88202482d1ffca24f37eeaa77cc Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Tue, 10 Nov 2020 09:40:50 +0000 Subject: [PATCH] checker: unify invalid argument errors, use argument position (#6785) --- vlib/v/checker/checker.v | 13 ++----------- vlib/v/checker/tests/fn_args.out | 19 +++++++++++++++++++ vlib/v/checker/tests/fn_args.vv | 8 ++++++++ .../checker/tests/function_wrong_arg_type.out | 4 ++-- vlib/v/checker/tests/is_type_not_exist.out | 8 ++++---- .../tests/non_matching_functional_args.out | 14 +++++++------- 6 files changed, 42 insertions(+), 24 deletions(-) create mode 100644 vlib/v/checker/tests/fn_args.out create mode 100644 vlib/v/checker/tests/fn_args.vv diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index f472cee813..1f0f1375c9 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1534,7 +1534,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { return true } */ - if !c.check_types(typ, arg.typ) { + c.check_expected(typ, arg.typ) or { // str method, allow type with str method if fn arg is string // Passing an int or a string array produces a c error here // Deleting this condition results in propper V error messages @@ -1547,16 +1547,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { if f.is_generic { continue } - if typ_sym.kind == .array_fixed { - } - if typ_sym.kind == .function && arg_typ_sym.kind == .function { - candidate_fn_name := if typ_sym.source_name.starts_with('anon_') { 'anonymous function' } else { 'fn `$typ_sym.source_name`' } - c.error('cannot use $candidate_fn_name as function type `$arg_typ_sym.str()` in argument ${i + - 1} to `$fn_name`', call_expr.pos) - } else { - c.error('cannot use type `$typ_sym.source_name` as type `$arg_typ_sym.source_name` in argument ${i + - 1} to `$fn_name`', call_expr.pos) - } + c.error('invalid argument ${i + 1} to `$fn_name`: $err', call_arg.pos) } } if f.is_generic && call_expr.generic_type == table.void_type { diff --git a/vlib/v/checker/tests/fn_args.out b/vlib/v/checker/tests/fn_args.out new file mode 100644 index 0000000000..fbd345e5d2 --- /dev/null +++ b/vlib/v/checker/tests/fn_args.out @@ -0,0 +1,19 @@ +vlib/v/checker/tests/fn_args.vv:6:7: 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` + 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)` + 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 diff --git a/vlib/v/checker/tests/fn_args.vv b/vlib/v/checker/tests/fn_args.vv new file mode 100644 index 0000000000..9065ed5ad1 --- /dev/null +++ b/vlib/v/checker/tests/fn_args.vv @@ -0,0 +1,8 @@ +fn ptr(a byte) {} +fn arr(a []int) {} +fn fun(a fn(int)) {} + +v := 4 +ptr(&v) +arr([5]!!) +fun(fn(i &int){}) diff --git a/vlib/v/checker/tests/function_wrong_arg_type.out b/vlib/v/checker/tests/function_wrong_arg_type.out index 68dd3932e6..cd6e0f3d07 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:7: error: cannot use type `f64` as type `int` in argument 1 to `f` +vlib/v/checker/tests/function_wrong_arg_type.vv:7:10: 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 | } diff --git a/vlib/v/checker/tests/is_type_not_exist.out b/vlib/v/checker/tests/is_type_not_exist.out index 77c3e8a54b..96ce48a3c6 100644 --- a/vlib/v/checker/tests/is_type_not_exist.out +++ b/vlib/v/checker/tests/is_type_not_exist.out @@ -1,12 +1,12 @@ -vlib/v/checker/tests/is_type_not_exist.vv:4:2: error: cannot use type `any_int` as type `Integer` in argument 1 to `fn_with_sum_type_param` - 2 | +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 | 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 { | ~~~~~~~~~~~~~~~~~~~~~~ diff --git a/vlib/v/checker/tests/non_matching_functional_args.out b/vlib/v/checker/tests/non_matching_functional_args.out index b30c3fba0e..472ae5ee68 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:27:2: error: cannot use anonymous function as function type `MyFn` in argument 1 to `sum` - 25 | - 26 | fn main() { - 27 | sum(fn (mut t Table) { - | ~~~~~~~~~~~~~~~~~~~~~~ +vlib/v/checker/tests/non_matching_functional_args.vv:30:3: error: invalid argument 1 to `sum`: expected `fn (Table)`, not `fn (mut 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:2: error: cannot use fn `xxx` as function type `MyFn` in argument 1 to `sum` +vlib/v/checker/tests/non_matching_functional_args.vv:31:9: 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