1
0
mirror of https://github.com/vlang/v.git synced 2023-08-10 21:13:21 +03:00

checker: check generic method call argument mismatch (#15378)

This commit is contained in:
yuyi 2022-08-08 22:30:48 +08:00 committed by GitHub
parent 5a834a2ef9
commit 9b88feccad
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 24 deletions

View File

@ -1382,30 +1382,6 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
final_arg_typ = exp_arg_sym.info.elem_type
final_arg_sym = c.table.sym(final_arg_typ)
}
if exp_arg_typ.has_flag(.generic) {
method_concrete_types := if method.generic_names.len == rec_concrete_types.len {
rec_concrete_types
} else {
concrete_types
}
if exp_utyp := c.table.resolve_generic_to_concrete(exp_arg_typ, method.generic_names,
method_concrete_types)
{
exp_arg_typ = exp_utyp
} else {
continue
}
if got_arg_typ.has_flag(.generic) {
if got_utyp := c.table.resolve_generic_to_concrete(got_arg_typ, method.generic_names,
method_concrete_types)
{
got_arg_typ = got_utyp
} else {
continue
}
}
}
param := if method.is_variadic && i >= method.params.len - 1 {
method.params.last()
} else {
@ -1442,6 +1418,30 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
c.fail_if_unreadable(arg.expr, got_arg_typ, 'argument')
}
}
if exp_arg_typ.has_flag(.generic) {
method_concrete_types := if method.generic_names.len == rec_concrete_types.len {
rec_concrete_types
} else {
concrete_types
}
if exp_utyp := c.table.resolve_generic_to_concrete(exp_arg_typ, method.generic_names,
method_concrete_types)
{
exp_arg_typ = exp_utyp
} else {
continue
}
if got_arg_typ.has_flag(.generic) {
if got_utyp := c.table.resolve_generic_to_concrete(got_arg_typ, method.generic_names,
method_concrete_types)
{
got_arg_typ = got_utyp
} else {
continue
}
}
}
if left_sym.info is ast.Array && method_name == 'sort_with_compare' {
elem_typ := left_sym.info.elem_type
arg_sym := c.table.sym(arg.typ)

View File

@ -0,0 +1,7 @@
vlib/v/checker/tests/generics_method_arg_type_err.vv:14:20: error: `node_create` parameter `t` is not `mut`, `mut` is not needed`
12 | name: 'Gecko'
13 | }
14 | r.node_create(mut g)
| ^
15 | }
16 |

View File

@ -0,0 +1,19 @@
module main
pub struct Redis {}
pub struct Reptile {
name string
}
fn main() {
mut r := Redis{}
mut g := Reptile{
name: 'Gecko'
}
r.node_create(mut g)
}
pub fn (mut r Redis) node_create<T>(t T) bool {
return true
}