From 245ed9160aef474073f21006013a48d04ce288a1 Mon Sep 17 00:00:00 2001 From: Ruofan XU <47302112+SleepyRoy@users.noreply.github.com> Date: Wed, 13 Jan 2021 21:52:46 +0800 Subject: [PATCH] gen: fix `mut arr [3]int` as a fn argument (#8085) --- vlib/v/gen/fn.v | 8 +++++++- vlib/v/parser/fn.v | 3 ++- vlib/v/tests/fixed_array_test.v | 25 ++++++++++++++++++++++--- 3 files changed, 31 insertions(+), 5 deletions(-) diff --git a/vlib/v/gen/fn.v b/vlib/v/gen/fn.v index 8a5aff08a5..47e906808e 100644 --- a/vlib/v/gen/fn.v +++ b/vlib/v/gen/fn.v @@ -240,7 +240,13 @@ fn (mut g Gen) fn_args(args []table.Param, is_variadic bool) ([]string, []string g.definitions.write(')') } } else { - s := arg_type_name + ' ' + caname + // TODO: combine two operations into one once ternary in expression is fixed + mut s := if arg_type_sym.kind == .array_fixed { + arg_type_name.trim('*') + } else { + arg_type_name + } + s += ' ' + caname g.write(s) g.definitions.write(s) fargs << caname diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 09a2314dae..66aca48df1 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -686,7 +686,8 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { fn (mut p Parser) check_fn_mutable_arguments(typ table.Type, pos token.Position) { sym := p.table.get_type_symbol(typ) - if sym.kind !in [.array, .struct_, .map, .placeholder, .sum_type] && !typ.is_ptr() && !typ.is_pointer() { + if sym.kind !in [.array, .array_fixed, .struct_, .map, .placeholder, .sum_type] && + !typ.is_ptr() && !typ.is_pointer() { p.error_with_pos('mutable arguments are only allowed for arrays, maps, structs and pointers\n' + 'return values instead: `fn foo(mut n $sym.name) {` => `fn foo(n $sym.name) $sym.name {`', pos) diff --git a/vlib/v/tests/fixed_array_test.v b/vlib/v/tests/fixed_array_test.v index 11fa7f128b..30fa1fe83f 100644 --- a/vlib/v/tests/fixed_array_test.v +++ b/vlib/v/tests/fixed_array_test.v @@ -2,7 +2,7 @@ fn test_fixed_array_can_be_assigned() { x := 2.32 mut v := [8]f64{} assert v[1] == 0 - v = [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]!! + v = [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]! assert v[1] == x v[1] = 2.0 for i, e in v { @@ -20,7 +20,7 @@ fn test_fixed_array_can_be_assigned() { fn test_fixed_array_can_be_used_in_declaration() { x := 2.32 - v := [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]!! + v := [1.0, x, 3.0,4.0,5.0,6.0,7.0,8.0]! assert v.len == 8 assert v[1] == x } @@ -35,7 +35,7 @@ fn test_fixed_array_can_be_assigned_to_a_struct_field() { mut ctx := Context{} assert ctx.vb.len == 8 x := 2.32 - ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]!! + ctx.vb = [1.1, x, 3.3, 4.4, 5.0, 6.0, 7.0, 8.9]! assert ctx.vb[1] == x assert ctx.vb[7] == 8.9 for i, e in ctx.vb { @@ -49,3 +49,22 @@ fn test_fixed_array_can_be_assigned_to_a_struct_field() { println( ctx.vb[3] ) */ } + +fn multiply_by_two(mut arr [3]int) { + for i in 0..arr.len { + arr[i] *= 2 + } +} + +fn change_first_element(mut arr [3][3]int) { + arr[0][0] = 0 +} + +fn test_fixed_array_can_be_passed_as_mut_arg() { + mut arr := [1,2,3]! + multiply_by_two(mut arr) + assert arr == [2,4,6]! + mut arr2 := [[1,2,3]!, [4,5,6]!, [7,8,9]!]! + change_first_element(mut arr2) + assert arr2 == [[0,2,3]!, [4,5,6]!, [7,8,9]!]! +}