diff --git a/vlib/v/checker/tests/function_arg_mutable_err.out b/vlib/v/checker/tests/function_arg_mutable_err.out index 2ecc3eee28..7bc75f0892 100644 --- a/vlib/v/checker/tests/function_arg_mutable_err.out +++ b/vlib/v/checker/tests/function_arg_mutable_err.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/function_arg_mutable_err.vv:1:18: error: mutable arguments are only allowed for arrays, maps, and structs +vlib/v/checker/tests/function_arg_mutable_err.vv:1:18: error: mutable arguments are only allowed for arrays, maps, structs and pointers return values instead: `fn foo(mut n int) {` => `fn foo(n int) int {` 1 | fn mod_ptr(mut a int) { | ~~~ diff --git a/vlib/v/checker/tests/mut_int.out b/vlib/v/checker/tests/mut_int.out index 852762c3ea..de06cdb105 100644 --- a/vlib/v/checker/tests/mut_int.out +++ b/vlib/v/checker/tests/mut_int.out @@ -1,4 +1,4 @@ -vlib/v/checker/tests/mut_int.vv:1:14: error: mutable arguments are only allowed for arrays, maps, and structs +vlib/v/checker/tests/mut_int.vv:1:14: error: mutable arguments are only allowed for arrays, maps, structs and pointers return values instead: `fn foo(mut n int) {` => `fn foo(n int) int {` 1 | fn foo(mut x int) { | ~~~ diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 144c21ca1d..aece0ca551 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -598,8 +598,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() { - p.error_with_pos('mutable arguments are only allowed for arrays, maps, and structs\n' + + if sym.kind !in [.array, .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/type_voidptr_test.v b/vlib/v/tests/type_voidptr_test.v new file mode 100644 index 0000000000..a2856128d3 --- /dev/null +++ b/vlib/v/tests/type_voidptr_test.v @@ -0,0 +1,21 @@ +[direct_array_access] +[unsafe] +fn memcpy(mut dest voidptr, src voidptr, len u32) voidptr { + mut d := byteptr(dest) + s := byteptr(src) + mut l := len + for l > 0 { + l-- + unsafe { + d[l] = s[l] + } + } + return dest +} + +fn test_mut_voidptr_arg() { + mut a := [1, 2]!! + b := [3, 4]!! + memcpy(mut a, b, sizeof(int)) + assert a == [3, 2]!! +}