checker: fix the argument mismatch of fn call (#12479)
parent
3fab0a5d05
commit
2984751a57
|
@ -1161,7 +1161,7 @@ fn is_excluding_latin(table &RangeTable, r rune) bool {
|
|||
}
|
||||
r32 := &table.r32
|
||||
if r32.len > 0 && r >= rune((*r32)[0].lo) {
|
||||
return is_32(r32, u32(r))
|
||||
return is_32(*r32, u32(r))
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@ module checker
|
|||
import v.ast
|
||||
import v.token
|
||||
|
||||
pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language) ? {
|
||||
pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, language ast.Language, arg ast.CallArg) ? {
|
||||
mut expected := expected_
|
||||
// variadic
|
||||
if expected.has_flag(.variadic) {
|
||||
|
@ -34,9 +34,6 @@ pub fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type,
|
|||
return
|
||||
}
|
||||
}
|
||||
if c.check_types(got, expected) {
|
||||
return
|
||||
}
|
||||
idx_got := got.idx()
|
||||
idx_expected := expected.idx()
|
||||
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,
|
|||
return
|
||||
}
|
||||
}
|
||||
if c.check_types(got, expected) {
|
||||
if language != .v || expected.is_ptr() == got.is_ptr() || arg.is_mut
|
||||
|| arg.expr.is_auto_deref_var() || got.has_flag(.shared_f)
|
||||
|| c.table.get_type_symbol(expected_).kind !in [.array, .map] {
|
||||
return
|
||||
}
|
||||
}
|
||||
return error('cannot use `${c.table.type_to_str(got.clear_flag(.variadic))}` as `${c.table.type_to_str(expected.clear_flag(.variadic))}`')
|
||||
}
|
||||
|
||||
|
|
|
@ -2185,7 +2185,8 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||
if exp_arg_typ.has_flag(.generic) {
|
||||
continue
|
||||
}
|
||||
c.check_expected_call_arg(got_arg_typ, c.unwrap_generic(exp_arg_typ), node.language) or {
|
||||
c.check_expected_call_arg(got_arg_typ, c.unwrap_generic(exp_arg_typ), node.language,
|
||||
arg) or {
|
||||
// str method, allow type with str method if fn arg is string
|
||||
// Passing an int or a string array produces a c error here
|
||||
// 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 {
|
|||
|
||||
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 {
|
||||
c.check_expected_call_arg(targ, c.unwrap_generic(exp_arg_typ), node.language,
|
||||
arg) or {
|
||||
if targ != ast.void_type {
|
||||
c.error('$err.msg in argument ${i + 1} to `${left_sym.name}.$method_name`',
|
||||
arg.pos)
|
||||
|
@ -2372,7 +2374,7 @@ fn (mut c Checker) map_builtin_method_call(mut node ast.CallExpr, left_type ast.
|
|||
}
|
||||
info := left_sym.info as ast.Map
|
||||
arg_type := c.expr(node.args[0].expr)
|
||||
c.check_expected_call_arg(arg_type, info.key_type, node.language) or {
|
||||
c.check_expected_call_arg(arg_type, info.key_type, node.language, node.args[0]) or {
|
||||
c.error('$err.msg in argument 1 to `Map.delete`', node.args[0].pos)
|
||||
}
|
||||
}
|
||||
|
@ -2866,7 +2868,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
|||
}
|
||||
continue
|
||||
}
|
||||
c.check_expected_call_arg(typ, c.unwrap_generic(param.typ), node.language) or {
|
||||
c.check_expected_call_arg(typ, c.unwrap_generic(param.typ), node.language, call_arg) or {
|
||||
// str method, allow type with str method if fn arg is string
|
||||
// Passing an int or a string array produces a c error here
|
||||
// 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)
|
|||
}
|
||||
continue
|
||||
}
|
||||
c.check_expected_call_arg(utyp, unwrap_typ, node.language) or {
|
||||
c.check_expected_call_arg(utyp, unwrap_typ, node.language, call_arg) or {
|
||||
c.error('$err.msg in argument ${i + 1} to `$fn_name`', call_arg.pos)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,7 @@
|
|||
vlib/v/checker/tests/fn_call_arg_mismatch.vv:7:9: error: cannot use `&[]int` as `[]int` in argument 1 to `abc`
|
||||
5 | fn main() {
|
||||
6 | a := [1, 2, 3]
|
||||
7 | go abc(&a)
|
||||
| ~~
|
||||
8 | println('done')
|
||||
9 | }
|
|
@ -0,0 +1,9 @@
|
|||
fn abc(x []int) {
|
||||
println(x)
|
||||
}
|
||||
|
||||
fn main() {
|
||||
a := [1, 2, 3]
|
||||
go abc(&a)
|
||||
println('done')
|
||||
}
|
Loading…
Reference in New Issue