diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index a6341ebc31..3650204d44 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -2924,11 +2924,18 @@ fn (mut g Gen) infix_expr(node ast.InfixExpr) { info := left_sym.info as table.Array if right_sym.kind == .array && info.elem_type != node.right_type { // push an array => PUSH_MANY, but not if pushing an array to 2d array (`[][]int << []int`) - g.write('_PUSH_MANY(&') + g.write('_PUSH_MANY(') + mut expected_push_many_atype := left_type + if !expected_push_many_atype.is_ptr() { + // fn f(mut a []int) { a << [1,2,3] } -> type of `a` is `array_int*` -> no need for & + g.write('&') + } else { + expected_push_many_atype = expected_push_many_atype.deref() + } g.expr(node.left) g.write(', (') g.expr_with_cast(node.right, node.right_type, left_type) - styp := g.typ(left_type) + styp := g.typ(expected_push_many_atype) g.write('), $tmp, $styp)') } else { // push a single element diff --git a/vlib/v/tests/appending_to_mut_array_in_fn_param_test.v b/vlib/v/tests/appending_to_mut_array_in_fn_param_test.v new file mode 100644 index 0000000000..bbaf401193 --- /dev/null +++ b/vlib/v/tests/appending_to_mut_array_in_fn_param_test.v @@ -0,0 +1,34 @@ +fn append_i(mut a []int) { + a << 1 // ensure single element << works + a << [2, 3] // .. and array << works too +} + +fn append_s(mut a []string) { + a << 'a' + a << ['b', 'c'] +} + +fn append_2d(mut a [][]int) { + a << [1] + a << [2, 3, 4] +} + +fn test_appending_to_mutable_int_array_args() { + mut xxx := [10, 20, 30] + append_i(mut xxx) + assert xxx == [10, 20, 30, 1, 2, 3] +} + +fn test_appending_to_mutable_string_array_args() { + mut xxx := ['x', 'y', 'z'] + append_s(mut xxx) + assert xxx == ['x', 'y', 'z', 'a', 'b', 'c'] +} + +fn test_appending_to_mutable_2d_array_args() { + mut xxx := [][]int{} + xxx << [1, 2, 3] + xxx << [3, 4, 5] + append_2d(mut xxx) + assert xxx == [[1, 2, 3], [3, 4, 5], [1], [2, 3, 4]] +}