Skip to content

Commit 2984751

Browse files
authored
checker: fix the argument mismatch of fn call (#12479)
1 parent 3fab0a5 commit 2984751

File tree

5 files changed

+32
-10
lines changed

5 files changed

+32
-10
lines changed

vlib/encoding/utf8/utf8_tables.v

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1161,7 +1161,7 @@ fn is_excluding_latin(table &RangeTable, r rune) bool {
11611161
}
11621162
r32 := &table.r32
11631163
if r32.len > 0 && r >= rune((*r32)[0].lo) {
1164-
return is_32(r32, u32(r))
1164+
return is_32(*r32, u32(r))
11651165
}
11661166
return false
11671167
}

vlib/v/checker/check_types.v

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ module checker
66
import v.ast
77
import v.token
88

9-
pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language) ? {
9+
pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language, arg ast.CallArg) ? {
1010
mut expected := expected_
1111
// variadic
1212
if expected.has_flag(.variadic) {
@@ -34,9 +34,6 @@ pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type,
3434
return
3535
}
3636
}
37-
if c.check_types(got, expected) {
38-
return
39-
}
4037
idx_got := got.idx()
4138
idx_expected := expected.idx()
4239
if idx_got in [ast.byteptr_type_idx, ast.charptr_type_idx]
@@ -72,6 +69,13 @@ pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type,
7269
return
7370
}
7471
}
72+
if c.check_types(got, expected) {
73+
if language != .v || expected.is_ptr() == got.is_ptr() || arg.is_mut
74+
|| arg.expr.is_auto_deref_var() || got.has_flag(.shared_f)
75+
|| c.table.get_type_symbol(expected_).kind !in [.array, .map] {
76+
return
77+
}
78+
}
7579
return error('cannot use `${c.table.type_to_str(got.clear_flag(.variadic))}` as `${c.table.type_to_str(expected.clear_flag(.variadic))}`')
7680
}
7781

vlib/v/checker/checker.v

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2185,7 +2185,8 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
21852185
if exp_arg_typ.has_flag(.generic) {
21862186
continue
21872187
}
2188-
c.check_expected_call_arg(got_arg_typ, c.unwrap_generic(exp_arg_typ), node.language) or {
2188+
c.check_expected_call_arg(got_arg_typ, c.unwrap_generic(exp_arg_typ), node.language,
2189+
arg) or {
21892190
// str method, allow type with str method if fn arg is string
21902191
// Passing an int or a string array produces a c error here
21912192
// Deleting this condition results in propper V error messages
@@ -2326,7 +2327,8 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
23262327

23272328
if i < info.func.params.len {
23282329
exp_arg_typ := info.func.params[i].typ
2329-
c.check_expected_call_arg(targ, c.unwrap_generic(exp_arg_typ), node.language) or {
2330+
c.check_expected_call_arg(targ, c.unwrap_generic(exp_arg_typ), node.language,
2331+
arg) or {
23302332
if targ != ast.void_type {
23312333
c.error('$err.msg in argument ${i + 1} to `${left_sym.name}.$method_name`',
23322334
arg.pos)
@@ -2372,7 +2374,7 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.
23722374
}
23732375
info := left_sym.info as ast.Map
23742376
arg_type := c.expr(node.args[0].expr)
2375-
c.check_expected_call_arg(arg_type, info.key_type, node.language) or {
2377+
c.check_expected_call_arg(arg_type, info.key_type, node.language, node.args[0]) or {
23762378
c.error('$err.msg in argument 1 to `Map.delete`', node.args[0].pos)
23772379
}
23782380
}
@@ -2866,7 +2868,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
28662868
}
28672869
continue
28682870
}
2869-
c.check_expected_call_arg(typ, c.unwrap_generic(param.typ), node.language) or {
2871+
c.check_expected_call_arg(typ, c.unwrap_generic(param.typ), node.language, call_arg) or {
28702872
// str method, allow type with str method if fn arg is string
28712873
// Passing an int or a string array produces a c error here
28722874
// Deleting this condition results in propper V error messages
@@ -2942,7 +2944,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
29422944
}
29432945
continue
29442946
}
2945-
c.check_expected_call_arg(utyp, unwrap_typ, node.language) or {
2947+
c.check_expected_call_arg(utyp, unwrap_typ, node.language, call_arg) or {
29462948
c.error('$err.msg in argument ${i + 1} to `$fn_name`', call_arg.pos)
29472949
}
29482950
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
vlib/v/checker/tests/fn_call_arg_mismatch.vv:7:9: error: cannot use `&[]int` as `[]int` in argument 1 to `abc`
2+
5 | fn main() {
3+
6 | a := [1, 2, 3]
4+
7 | go abc(&a)
5+
| ~~
6+
8 | println('done')
7+
9 | }
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
fn abc(x []int) {
2+
println(x)
3+
}
4+
5+
fn main() {
6+
a := [1, 2, 3]
7+
go abc(&a)
8+
println('done')
9+
}

0 commit comments

Comments
 (0)