checker: check generic struct field fn args type mismatch (#12379)

pull/12387/head
yuyi 2021-11-04 16:18:36 +08:00 committed by GitHub
parent a27833ed0d
commit 73e25ccb3c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 41 additions and 4 deletions

View File

@ -2280,15 +2280,27 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
node.is_method = false
node.is_field = true
info := field_type_sym.info as ast.FnType
c.check_expected_arg_count(mut node, info.func) or { return info.func.return_type }
node.return_type = info.func.return_type
mut earg_types := []ast.Type{}
for mut arg in node.args {
for i, mut arg in node.args {
targ := c.check_expr_opt_call(arg.expr, c.expr(arg.expr))
arg.typ = targ
earg_types << targ
if i < info.func.params.len {
exp_arg_typ := info.func.params[i].typ
c.check_expected_call_arg(targ, c.unwrap_generic(exp_arg_typ), node.language) or {
if targ != ast.void_type {
c.error('$err.msg in argument ${i + 1} to `${left_type_sym.name}.$method_name`',
arg.pos)
}
}
}
}
node.expected_arg_types = earg_types
c.check_expected_arg_count(mut node, info.func) or { return info.func.return_type }
node.is_method = true
return info.func.return_type
}

View File

@ -18,10 +18,31 @@ vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:29:15: error: expected
29 | println(fun1.call())
| ~~~~~~
30 | println(fun1.call(42, 43))
31 | }
31 |
vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:30:24: error: expected 1 arguments, but got 2
28 | println(fun1.call(42))
29 | println(fun1.call())
30 | println(fun1.call(42, 43))
| ~~
31 | }
31 |
32 | println(fun1.call(true))
vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:32:20: error: cannot use `bool` as `int` in argument 1 to `Fun<fn (int) int>.call`
30 | println(fun1.call(42, 43))
31 |
32 | println(fun1.call(true))
| ~~~~
33 | println(fun1.call('text'))
34 | println(fun1.call(22.2))
vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:33:20: error: cannot use `string` as `int` in argument 1 to `Fun<fn (int) int>.call`
31 |
32 | println(fun1.call(true))
33 | println(fun1.call('text'))
| ~~~~~~
34 | println(fun1.call(22.2))
35 | }
vlib/v/checker/tests/generics_struct_field_fn_args_err.vv:34:20: error: cannot use `float literal` as `int` in argument 1 to `Fun<fn (int) int>.call`
32 | println(fun1.call(true))
33 | println(fun1.call('text'))
34 | println(fun1.call(22.2))
| ~~~~
35 | }

View File

@ -28,4 +28,8 @@ fn main() {
println(fun1.call(42))
println(fun1.call())
println(fun1.call(42, 43))
println(fun1.call(true))
println(fun1.call('text'))
println(fun1.call(22.2))
}