diff --git a/vlib/crypto/blake3/blake3_chunk_test.v b/vlib/crypto/blake3/blake3_chunk_test.v index babd319f72c0ae..2fe2b3e87c5b6c 100644 --- a/vlib/crypto/blake3/blake3_chunk_test.v +++ b/vlib/crypto/blake3/blake3_chunk_test.v @@ -51,7 +51,7 @@ const test_cases = [ } results: Chunk{ chunk_number: 0 - chaining_value: iv + chaining_value: iv.clone() block_words: [u32(0), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flags: 0x0b } @@ -69,7 +69,7 @@ const test_cases = [ } results: Chunk{ chunk_number: 0 - chaining_value: iv + chaining_value: iv.clone() block_words: [u32(0x00000041), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flags: 0x0b } @@ -87,7 +87,7 @@ const test_cases = [ } results: Chunk{ chunk_number: 0 - chaining_value: iv + chaining_value: iv.clone() block_words: [u32(0x00636261), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flags: 0x0b } @@ -105,7 +105,7 @@ const test_cases = [ } results: Chunk{ chunk_number: 0 - chaining_value: iv + chaining_value: iv.clone() block_words: [u32(0x44434241), 0x48474645, 0x4c4b4a49, 0x504f4e4d, 0x54535251, 0x58575655, 0x61205a59, 0x65646362, 0x69686766, 0x6d6c6b6a, 0x71706f6e, 0x75747372, 0x79787776, 0x3130207a, 0x35343332, 0x00383736] @@ -125,7 +125,7 @@ const test_cases = [ } results: Chunk{ chunk_number: 0 - chaining_value: iv + chaining_value: iv.clone() block_words: [u32(0x44434241), 0x48474645, 0x4c4b4a49, 0x504f4e4d, 0x54535251, 0x58575655, 0x61205a59, 0x65646362, 0x69686766, 0x6d6c6b6a, 0x71706f6e, 0x75747372, 0x79787776, 0x3130207a, 0x35343332, 0x39383736] @@ -269,7 +269,7 @@ const test_cases = [ } results: Chunk{ chunk_number: 1 - chaining_value: iv + chaining_value: iv.clone() block_words: [u32(0x0000004f), 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0] flags: 0x0b } diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index c99a161247d652..e261c303891ab2 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -745,6 +745,13 @@ or use an explicit `unsafe{ a[..] }`, if you do not want a copy of the slice.', got_type = c.expr(mut right) node.init_fields[i].expr = right } + // disallow `mut a: b`, when b is const array + if field_info.is_mut + && (init_field.expr is ast.Ident && init_field.expr.obj is ast.ConstField) + && !c.inside_unsafe { + c.error('cannot assign a const array to mut struct field, call `clone` method (or use `unsafe`)', + init_field.expr.pos()) + } } if exp_type_sym.kind == .interface { if c.type_implements(got_type, exp_type, init_field.pos) { diff --git a/vlib/v/checker/tests/struct_arr_mut_field_arr_assign_err.out b/vlib/v/checker/tests/struct_arr_mut_field_arr_assign_err.out new file mode 100644 index 00000000000000..298a227bf3a196 --- /dev/null +++ b/vlib/v/checker/tests/struct_arr_mut_field_arr_assign_err.out @@ -0,0 +1,7 @@ +vlib/v/checker/tests/struct_arr_mut_field_arr_assign_err.vv:10:6: error: cannot assign a const array to mut struct field, call `clone` method (or use `unsafe`) + 8 | fn main() { + 9 | mut muta := Muta{ + 10 | a: arr + | ~~~ + 11 | } + 12 | muta.a[0] = 52 diff --git a/vlib/v/checker/tests/struct_arr_mut_field_arr_assign_err.vv b/vlib/v/checker/tests/struct_arr_mut_field_arr_assign_err.vv new file mode 100644 index 00000000000000..84ed30ca6a4b3f --- /dev/null +++ b/vlib/v/checker/tests/struct_arr_mut_field_arr_assign_err.vv @@ -0,0 +1,14 @@ +const arr = [1, 2, 3] + +struct Muta { +mut: + a []int +} + +fn main() { + mut muta := Muta{ + a: arr + } + muta.a[0] = 52 + println(arr) // [52, 2, 3] +}