Skip to content

Commit 9b88fec

Browse files
authored
checker: check generic method call argument mismatch (#15378)
1 parent 5a834a2 commit 9b88fec

File tree

3 files changed

+50
-24
lines changed

3 files changed

+50
-24
lines changed

vlib/v/checker/fn.v

Lines changed: 24 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -1382,30 +1382,6 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
13821382
final_arg_typ = exp_arg_sym.info.elem_type
13831383
final_arg_sym = c.table.sym(final_arg_typ)
13841384
}
1385-
if exp_arg_typ.has_flag(.generic) {
1386-
method_concrete_types := if method.generic_names.len == rec_concrete_types.len {
1387-
rec_concrete_types
1388-
} else {
1389-
concrete_types
1390-
}
1391-
if exp_utyp := c.table.resolve_generic_to_concrete(exp_arg_typ, method.generic_names,
1392-
method_concrete_types)
1393-
{
1394-
exp_arg_typ = exp_utyp
1395-
} else {
1396-
continue
1397-
}
1398-
1399-
if got_arg_typ.has_flag(.generic) {
1400-
if got_utyp := c.table.resolve_generic_to_concrete(got_arg_typ, method.generic_names,
1401-
method_concrete_types)
1402-
{
1403-
got_arg_typ = got_utyp
1404-
} else {
1405-
continue
1406-
}
1407-
}
1408-
}
14091385
param := if method.is_variadic && i >= method.params.len - 1 {
14101386
method.params.last()
14111387
} else {
@@ -1442,6 +1418,30 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
14421418
c.fail_if_unreadable(arg.expr, got_arg_typ, 'argument')
14431419
}
14441420
}
1421+
if exp_arg_typ.has_flag(.generic) {
1422+
method_concrete_types := if method.generic_names.len == rec_concrete_types.len {
1423+
rec_concrete_types
1424+
} else {
1425+
concrete_types
1426+
}
1427+
if exp_utyp := c.table.resolve_generic_to_concrete(exp_arg_typ, method.generic_names,
1428+
method_concrete_types)
1429+
{
1430+
exp_arg_typ = exp_utyp
1431+
} else {
1432+
continue
1433+
}
1434+
1435+
if got_arg_typ.has_flag(.generic) {
1436+
if got_utyp := c.table.resolve_generic_to_concrete(got_arg_typ, method.generic_names,
1437+
method_concrete_types)
1438+
{
1439+
got_arg_typ = got_utyp
1440+
} else {
1441+
continue
1442+
}
1443+
}
1444+
}
14451445
if left_sym.info is ast.Array && method_name == 'sort_with_compare' {
14461446
elem_typ := left_sym.info.elem_type
14471447
arg_sym := c.table.sym(arg.typ)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/checker/tests/generics_method_arg_type_err.vv:14:20: error: `node_create` parameter `t` is not `mut`, `mut` is not needed`
2+
12 | name: 'Gecko'
3+
13 | }
4+
14 | r.node_create(mut g)
5+
| ^
6+
15 | }
7+
16 |
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
module main
2+
3+
pub struct Redis {}
4+
5+
pub struct Reptile {
6+
name string
7+
}
8+
9+
fn main() {
10+
mut r := Redis{}
11+
mut g := Reptile{
12+
name: 'Gecko'
13+
}
14+
r.node_create(mut g)
15+
}
16+
17+
pub fn (mut r Redis) node_create<T>(t T) bool {
18+
return true
19+
}

0 commit comments

Comments
 (0)