mirror of
https://github.com/vlang/v.git
synced 2023-08-10 21:13:21 +03:00
This commit is contained in:
parent
07310d850d
commit
f8a28b5a5d
@ -941,6 +941,7 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool)
|
|||||||
typ := c.expr(call_arg.expr)
|
typ := c.expr(call_arg.expr)
|
||||||
if i == node.args.len - 1 {
|
if i == node.args.len - 1 {
|
||||||
if c.table.sym(typ).kind == .array && call_arg.expr !is ast.ArrayDecompose
|
if c.table.sym(typ).kind == .array && call_arg.expr !is ast.ArrayDecompose
|
||||||
|
&& c.table.sym(expected_type).kind !in [.sum_type, .interface_]
|
||||||
&& !param.typ.has_flag(.generic) && expected_type != typ {
|
&& !param.typ.has_flag(.generic) && expected_type != typ {
|
||||||
styp := c.table.type_to_str(typ)
|
styp := c.table.type_to_str(typ)
|
||||||
elem_styp := c.table.type_to_str(expected_type)
|
elem_styp := c.table.type_to_str(expected_type)
|
||||||
@ -1533,6 +1534,42 @@ pub fn (mut c Checker) method_call(mut node ast.CallExpr) ast.Type {
|
|||||||
} else {
|
} else {
|
||||||
method.params[i + 1]
|
method.params[i + 1]
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if method.is_variadic && arg.expr is ast.ArrayDecompose {
|
||||||
|
if i > method.params.len - 2 {
|
||||||
|
c.error('too many arguments in call to `$method.name`', node.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if method.is_variadic && i >= method.params.len - 2 {
|
||||||
|
param_sym := c.table.sym(param.typ)
|
||||||
|
mut expected_type := param.typ
|
||||||
|
if param_sym.kind == .array {
|
||||||
|
info := param_sym.array_info()
|
||||||
|
expected_type = info.elem_type
|
||||||
|
c.expected_type = expected_type
|
||||||
|
}
|
||||||
|
typ := c.expr(arg.expr)
|
||||||
|
if i == node.args.len - 1 {
|
||||||
|
if c.table.sym(typ).kind == .array && arg.expr !is ast.ArrayDecompose
|
||||||
|
&& c.table.sym(expected_type).kind !in [.sum_type, .interface_]
|
||||||
|
&& !param.typ.has_flag(.generic) && expected_type != typ {
|
||||||
|
styp := c.table.type_to_str(typ)
|
||||||
|
elem_styp := c.table.type_to_str(expected_type)
|
||||||
|
c.error('to pass `$arg.expr` ($styp) to `$method.name` (which accepts type `...$elem_styp`), use `...$arg.expr`',
|
||||||
|
node.pos)
|
||||||
|
} else if arg.expr is ast.ArrayDecompose
|
||||||
|
&& c.table.sym(expected_type).kind == .sum_type
|
||||||
|
&& expected_type.idx() != typ.idx() {
|
||||||
|
expected_type_str := c.table.type_to_str(expected_type)
|
||||||
|
got_type_str := c.table.type_to_str(typ)
|
||||||
|
c.error('cannot use `...$got_type_str` as `...$expected_type_str` in argument ${
|
||||||
|
i + 1} to `$method_name`', arg.pos)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
c.expected_type = param.typ
|
||||||
|
}
|
||||||
|
|
||||||
param_is_mut = param_is_mut || param.is_mut
|
param_is_mut = param_is_mut || param.is_mut
|
||||||
param_share := param.typ.share()
|
param_share := param.typ.share()
|
||||||
if param_share == .shared_t && (c.locked_names.len > 0 || c.rlocked_names.len > 0) {
|
if param_share == .shared_t && (c.locked_names.len > 0 || c.rlocked_names.len > 0) {
|
||||||
|
@ -0,0 +1,7 @@
|
|||||||
|
vlib/v/checker/tests/generics_method_called_variadic_arg_mismatch.vv:8:4: error: to pass `options` (string) to `req` (which accepts type `...string`), use `...options`
|
||||||
|
6 |
|
||||||
|
7 | fn (c Client) products_list(options ...string) {
|
||||||
|
8 | c.req<Product>(options) // (...options) works
|
||||||
|
| ~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
9 | }
|
||||||
|
10 |
|
@ -0,0 +1,14 @@
|
|||||||
|
struct Client {}
|
||||||
|
|
||||||
|
fn (cl Client) req<T>(data ...string) {}
|
||||||
|
|
||||||
|
struct Product {}
|
||||||
|
|
||||||
|
fn (c Client) products_list(options ...string) {
|
||||||
|
c.req<Product>(options) // (...options) works
|
||||||
|
}
|
||||||
|
|
||||||
|
fn main() {
|
||||||
|
mut sc := Client{}
|
||||||
|
sc.products_list()
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user