From 57d1b5b74d791f347e0bf2a99d8bd216bb31dbed Mon Sep 17 00:00:00 2001 From: Nick Treleaven Date: Wed, 24 Feb 2021 18:35:32 +0000 Subject: [PATCH] checker: show position for variadic/shared/method argument errors (#8939) --- vlib/v/checker/checker.v | 14 +++++------ vlib/v/checker/tests/fn_variadic.out | 14 +++++++++++ vlib/v/checker/tests/fn_variadic.vv | 13 +++++++++++ .../tests/function_variadic_arg_non_final.out | 5 ---- .../v/checker/tests/method_wrong_arg_type.out | 8 +++---- vlib/v/checker/tests/shared_lock.out | 21 +++++++++++++++++ vlib/v/checker/tests/shared_lock.vv | 23 +++++++++++++++++++ .../tests/function_variadic_arg_non_final.out | 5 ++++ .../tests/function_variadic_arg_non_final.vv | 0 9 files changed, 87 insertions(+), 16 deletions(-) create mode 100644 vlib/v/checker/tests/fn_variadic.out create mode 100644 vlib/v/checker/tests/fn_variadic.vv delete mode 100644 vlib/v/checker/tests/function_variadic_arg_non_final.out create mode 100644 vlib/v/checker/tests/shared_lock.out create mode 100644 vlib/v/checker/tests/shared_lock.vv create mode 100644 vlib/v/parser/tests/function_variadic_arg_non_final.out rename vlib/v/{checker => parser}/tests/function_variadic_arg_non_final.vv (100%) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 3a003eb7f1..bd3bea8606 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1526,8 +1526,8 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { got_arg_typ := 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 varg variable, it must be the final argument', - call_expr.pos) + c.error('when forwarding a variadic variable, it must be the final argument', + arg.pos) } if exp_arg_sym.kind == .interface_ { c.type_implements(got_arg_typ, exp_arg_typ, arg.expr.position()) @@ -1545,7 +1545,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { // } if got_arg_typ != table.void_type { c.error('$err in argument ${i + 1} to `${left_type_sym.name}.$method_name`', - call_expr.pos) + arg.pos) } } param := if method.is_variadic && i >= method.params.len - 1 { @@ -1556,7 +1556,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { param_share := param.typ.share() if param_share == .shared_t && (c.locked_names.len > 0 || c.rlocked_names.len > 0) { c.error('method with `shared` arguments cannot be called inside `lock`/`rlock` block', - call_expr.pos) + arg.pos) } if arg.is_mut { to_lock, pos := c.fail_if_immutable(arg.expr) @@ -1932,13 +1932,13 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { typ_sym := c.table.get_type_symbol(typ) arg_typ_sym := c.table.get_type_symbol(arg.typ) if f.is_variadic && typ.has_flag(.variadic) && call_expr.args.len - 1 > i { - c.error('when forwarding a varg variable, it must be the final argument', - call_expr.pos) + c.error('when forwarding a variadic variable, it must be the final argument', + call_arg.pos) } arg_share := arg.typ.share() if arg_share == .shared_t && (c.locked_names.len > 0 || c.rlocked_names.len > 0) { c.error('function with `shared` arguments cannot be called inside `lock`/`rlock` block', - call_expr.pos) + call_arg.pos) } if call_arg.is_mut { to_lock, pos := c.fail_if_immutable(call_arg.expr) diff --git a/vlib/v/checker/tests/fn_variadic.out b/vlib/v/checker/tests/fn_variadic.out new file mode 100644 index 0000000000..f14183a17e --- /dev/null +++ b/vlib/v/checker/tests/fn_variadic.out @@ -0,0 +1,14 @@ +vlib/v/checker/tests/fn_variadic.vv:3:8: error: when forwarding a variadic variable, it must be the final argument + 1 | fn f(vi ...int) int { + 2 | _ = f(...vi) // OK + 3 | _ = f(...vi, 2) + | ~~~~~ + 4 | return 0 + 5 | } +vlib/v/checker/tests/fn_variadic.vv:11:10: error: when forwarding a variadic variable, it must be the final argument + 9 | fn (s S1) m(vi ...int) int { + 10 | _ = s.m(...vi) // OK + 11 | _ = s.m(...vi, 2) + | ~~~~~ + 12 | return 0 + 13 | } diff --git a/vlib/v/checker/tests/fn_variadic.vv b/vlib/v/checker/tests/fn_variadic.vv new file mode 100644 index 0000000000..b7faad7444 --- /dev/null +++ b/vlib/v/checker/tests/fn_variadic.vv @@ -0,0 +1,13 @@ +fn f(vi ...int) int { + _ = f(...vi) // OK + _ = f(...vi, 2) + return 0 +} + +struct S1 {} + +fn (s S1) m(vi ...int) int { + _ = s.m(...vi) // OK + _ = s.m(...vi, 2) + return 0 +} diff --git a/vlib/v/checker/tests/function_variadic_arg_non_final.out b/vlib/v/checker/tests/function_variadic_arg_non_final.out deleted file mode 100644 index 338928c471..0000000000 --- a/vlib/v/checker/tests/function_variadic_arg_non_final.out +++ /dev/null @@ -1,5 +0,0 @@ -vlib/v/checker/tests/function_variadic_arg_non_final.vv:1:6: error: cannot use ...(variadic) with non-final parameter para1 - 1 | fn f(para1 ...int, para2 f32) int { - | ~~~~~ - 2 | return 22 - 3 | } diff --git a/vlib/v/checker/tests/method_wrong_arg_type.out b/vlib/v/checker/tests/method_wrong_arg_type.out index a2a7e732e4..c5175b308f 100644 --- a/vlib/v/checker/tests/method_wrong_arg_type.out +++ b/vlib/v/checker/tests/method_wrong_arg_type.out @@ -1,13 +1,13 @@ -vlib/v/checker/tests/method_wrong_arg_type.vv:10:4: error: cannot use `MyEnum` as `string` in argument 1 to `Sss.info` +vlib/v/checker/tests/method_wrong_arg_type.vv:10:9: error: cannot use `MyEnum` as `string` in argument 1 to `Sss.info` 8 | e := MyEnum.x 9 | s := Sss{} 10 | s.info(e) - | ~~~~~~~ + | ^ 11 | } 12 | -vlib/v/checker/tests/method_wrong_arg_type.vv:18:4: error: cannot use `int` as `&Sss` in argument 1 to `Sss.ptr` +vlib/v/checker/tests/method_wrong_arg_type.vv:18:8: error: cannot use `int` as `&Sss` in argument 1 to `Sss.ptr` 16 | s := Sss{} 17 | v := 4 18 | s.ptr(v) - | ~~~~~~ + | ^ 19 | } diff --git a/vlib/v/checker/tests/shared_lock.out b/vlib/v/checker/tests/shared_lock.out new file mode 100644 index 0000000000..62d71304a4 --- /dev/null +++ b/vlib/v/checker/tests/shared_lock.out @@ -0,0 +1,21 @@ +vlib/v/checker/tests/shared_lock.vv:19:5: error: method with `shared` receiver cannot be called inside `lock`/`rlock` block + 17 | } + 18 | lock x { + 19 | x.r(x) + | ~~~~ + 20 | x.m(x) + 21 | f(0, x) +vlib/v/checker/tests/shared_lock.vv:20:7: error: method with `shared` arguments cannot be called inside `lock`/`rlock` block + 18 | lock x { + 19 | x.r(x) + 20 | x.m(x) + | ^ + 21 | f(0, x) + 22 | } +vlib/v/checker/tests/shared_lock.vv:21:8: error: function with `shared` arguments cannot be called inside `lock`/`rlock` block + 19 | x.r(x) + 20 | x.m(x) + 21 | f(0, x) + | ^ + 22 | } + 23 | } diff --git a/vlib/v/checker/tests/shared_lock.vv b/vlib/v/checker/tests/shared_lock.vv new file mode 100644 index 0000000000..9af81113f8 --- /dev/null +++ b/vlib/v/checker/tests/shared_lock.vv @@ -0,0 +1,23 @@ +struct St { +mut: + a int +} +fn (shared s St) r(x St) { +} +fn (s St) m(shared x St) { +} + + +fn f(w int, shared x St) { +} + +fn g() { + shared x := St{ + a: 5 + } + lock x { + x.r(x) + x.m(x) + f(0, x) + } +} diff --git a/vlib/v/parser/tests/function_variadic_arg_non_final.out b/vlib/v/parser/tests/function_variadic_arg_non_final.out new file mode 100644 index 0000000000..7c69a4b6e7 --- /dev/null +++ b/vlib/v/parser/tests/function_variadic_arg_non_final.out @@ -0,0 +1,5 @@ +vlib/v/parser/tests/function_variadic_arg_non_final.vv:1:6: error: cannot use ...(variadic) with non-final parameter para1 + 1 | fn f(para1 ...int, para2 f32) int { + | ~~~~~ + 2 | return 22 + 3 | } diff --git a/vlib/v/checker/tests/function_variadic_arg_non_final.vv b/vlib/v/parser/tests/function_variadic_arg_non_final.vv similarity index 100% rename from vlib/v/checker/tests/function_variadic_arg_non_final.vv rename to vlib/v/parser/tests/function_variadic_arg_non_final.vv