checker: show position for variadic/shared/method argument errors (#8939)
parent
3c94a79375
commit
57d1b5b74d
|
@ -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)
|
got_arg_typ := c.expr(arg.expr)
|
||||||
call_expr.args[i].typ = got_arg_typ
|
call_expr.args[i].typ = got_arg_typ
|
||||||
if method.is_variadic && got_arg_typ.has_flag(.variadic) && call_expr.args.len - 1 > i {
|
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',
|
c.error('when forwarding a variadic variable, it must be the final argument',
|
||||||
call_expr.pos)
|
arg.pos)
|
||||||
}
|
}
|
||||||
if exp_arg_sym.kind == .interface_ {
|
if exp_arg_sym.kind == .interface_ {
|
||||||
c.type_implements(got_arg_typ, exp_arg_typ, arg.expr.position())
|
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 {
|
if got_arg_typ != table.void_type {
|
||||||
c.error('$err in argument ${i + 1} to `${left_type_sym.name}.$method_name`',
|
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 {
|
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()
|
param_share := param.typ.share()
|
||||||
if param_share == .shared_t && (c.locked_names.len > 0 || c.rlocked_names.len > 0) {
|
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',
|
c.error('method with `shared` arguments cannot be called inside `lock`/`rlock` block',
|
||||||
call_expr.pos)
|
arg.pos)
|
||||||
}
|
}
|
||||||
if arg.is_mut {
|
if arg.is_mut {
|
||||||
to_lock, pos := c.fail_if_immutable(arg.expr)
|
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)
|
typ_sym := c.table.get_type_symbol(typ)
|
||||||
arg_typ_sym := c.table.get_type_symbol(arg.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 {
|
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',
|
c.error('when forwarding a variadic variable, it must be the final argument',
|
||||||
call_expr.pos)
|
call_arg.pos)
|
||||||
}
|
}
|
||||||
arg_share := arg.typ.share()
|
arg_share := arg.typ.share()
|
||||||
if arg_share == .shared_t && (c.locked_names.len > 0 || c.rlocked_names.len > 0) {
|
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',
|
c.error('function with `shared` arguments cannot be called inside `lock`/`rlock` block',
|
||||||
call_expr.pos)
|
call_arg.pos)
|
||||||
}
|
}
|
||||||
if call_arg.is_mut {
|
if call_arg.is_mut {
|
||||||
to_lock, pos := c.fail_if_immutable(call_arg.expr)
|
to_lock, pos := c.fail_if_immutable(call_arg.expr)
|
||||||
|
|
|
@ -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 | }
|
|
@ -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
|
||||||
|
}
|
|
@ -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 | }
|
|
|
@ -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
|
8 | e := MyEnum.x
|
||||||
9 | s := Sss{}
|
9 | s := Sss{}
|
||||||
10 | s.info(e)
|
10 | s.info(e)
|
||||||
| ~~~~~~~
|
| ^
|
||||||
11 | }
|
11 | }
|
||||||
12 |
|
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{}
|
16 | s := Sss{}
|
||||||
17 | v := 4
|
17 | v := 4
|
||||||
18 | s.ptr(v)
|
18 | s.ptr(v)
|
||||||
| ~~~~~~
|
| ^
|
||||||
19 | }
|
19 | }
|
||||||
|
|
|
@ -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 | }
|
|
@ -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)
|
||||||
|
}
|
||||||
|
}
|
|
@ -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 | }
|
Loading…
Reference in New Issue