diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index b750d1f7e27eb1..c42239c3037d57 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -901,24 +901,27 @@ pub fn (mut c Checker) fn_call(mut node ast.CallExpr, mut continue_check &bool) } if func.is_variadic && i >= func.params.len - 1 { param_sym := c.table.sym(param.typ) + mut expected_type := param.typ if param_sym.kind == .array { info := param_sym.array_info() - c.expected_type = info.elem_type + expected_type = info.elem_type + c.expected_type = expected_type } typ := c.expr(call_arg.expr) if i == node.args.len - 1 { if c.table.sym(typ).kind == .array && call_arg.expr !is ast.ArrayDecompose - && !param.typ.has_flag(.generic) && c.expected_type != typ { + && !param.typ.has_flag(.generic) && expected_type != typ { styp := c.table.type_to_str(typ) - elem_styp := c.table.type_to_str(c.expected_type) + elem_styp := c.table.type_to_str(expected_type) c.error('to pass `$call_arg.expr` ($styp) to `$func.name` (which accepts type `...$elem_styp`), use `...$call_arg.expr`', node.pos) } else if call_arg.expr is ast.ArrayDecompose - && c.table.sym(c.expected_type).kind == .sum_type && c.expected_type != typ { - expected_type := c.table.type_to_str(c.expected_type) - got_type := c.table.type_to_str(typ) - c.error('cannot use `...$got_type` as `...$expected_type` in argument ${i + 1} to `$fn_name`', - call_arg.pos) + && 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 `$fn_name`', call_arg.pos) } } } else { diff --git a/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err.out b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_a.out similarity index 52% rename from vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err.out rename to vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_a.out index e12314eeac3cd6..dddcdf2efab65a 100644 --- a/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err.out +++ b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_a.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err.vv:12:7: error: cannot use `...string` as `...Any` in argument 1 to `test` +vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_a.vv:12:7: error: cannot use `...string` as `...Any` in argument 1 to `test` 10 | mut args := []string{cap: 3} 11 | args << ['test', 'test1', 'test2'] 12 | test(...args) diff --git a/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err.vv b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_a.vv similarity index 100% rename from vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err.vv rename to vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_a.vv diff --git a/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.out b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.out new file mode 100644 index 00000000000000..20b3daf8a1fcba --- /dev/null +++ b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.out @@ -0,0 +1,6 @@ +vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.vv:14:4: error: cannot use `...Foo1` as `...Foo` in argument 1 to `f` + 12 | + 13 | fn main() { + 14 | f(...[Foo1{}, Foo1{}]) + | ~~~~~~~~~~~~~~~~~~~ + 15 | } diff --git a/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.vv b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.vv new file mode 100644 index 00000000000000..44c5ca8188e98a --- /dev/null +++ b/vlib/v/checker/tests/fn_array_decompose_arg_mismatch_err_b.vv @@ -0,0 +1,15 @@ +struct Foo1 { +} + +struct Foo2 { +} + +type Foo = Foo1 | Foo2 + +fn f(v ...Foo) { + println(v) +} + +fn main() { + f(...[Foo1{}, Foo1{}]) +}