diff --git a/vlib/builtin/array.v b/vlib/builtin/array.v index ccab94f3c5..7cead83589 100644 --- a/vlib/builtin/array.v +++ b/vlib/builtin/array.v @@ -43,6 +43,21 @@ fn __new_array_with_default(mylen int, cap int, elm_size int, val voidptr) array return arr } +fn __new_array_with_array_default(mylen int, cap int, elm_size int, val array) array { + cap_ := if cap < mylen { mylen } else { cap } + arr := array{ + element_size: elm_size + data: vcalloc(cap_ * elm_size) + len: mylen + cap: cap_ + } + for i in 0..arr.len { + val_clone := val.clone() + C.memcpy(charptr(arr.data) + i*elm_size, &val_clone, elm_size) + } + return arr +} + // Private function, used by V (`nums := [1, 2, 3]`) fn new_array_from_c_array(len, cap, elm_size int, c_array voidptr) array { cap_ := if cap < len { len } else { cap } @@ -146,7 +161,7 @@ pub fn (mut a array) delete(i int) { } } size := a.element_size - // NB: if a is [12,34], a.len = 2, a.delete(0) + // NB: if a is [12,34], a.len = 2, a.delete(0) // should move (2-0-1) elements = 1 element (the 34) forward C.memmove(byteptr(a.data) + i * size, byteptr(a.data) + (i + 1) * size, (a.len - i - 1) * size) a.len-- diff --git a/vlib/builtin/array_test.v b/vlib/builtin/array_test.v index ce94ac592e..c7ebd82f46 100644 --- a/vlib/builtin/array_test.v +++ b/vlib/builtin/array_test.v @@ -816,3 +816,9 @@ fn test_array_with_cap() { assert a5.len == 1 assert a5.cap == 10 } + +fn test_mutli_array_index() { + mut a := [][]int{len:2, init: []int{len:3, init:0}} + a[0][0] = 1 + assert '$a' == '[[1, 0, 0], [0, 0, 0]]' +} diff --git a/vlib/v/gen/cgen.v b/vlib/v/gen/cgen.v index 0514ba7acf..bd969e8a79 100644 --- a/vlib/v/gen/cgen.v +++ b/vlib/v/gen/cgen.v @@ -3356,7 +3356,7 @@ fn (mut g Gen) or_block(var_name string, or_block ast.OrExpr, return_type table. } else { // In ordinary functions, `opt()?` call is sugar for: // `opt() or { return error(err) }` - // Since we *do* return, first we have to ensure that + // Since we *do* return, first we have to ensure that // the defered statements are generated. g.write_defer_stmts() // Now that option types are distinct we need a cast here @@ -4320,10 +4320,16 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { g.write('}') return } - // elem_sym := g.table.get_type_symbol(it.elem_type) elem_type_str := g.typ(it.elem_type) if it.exprs.len == 0 { - g.write('__new_array_with_default(') + elem_sym := g.table.get_type_symbol(it.elem_type) + is_default_array := elem_sym.kind == .array && it.has_default + + if is_default_array { + g.write('__new_array_with_array_default(') + } else { + g.write('__new_array_with_default(') + } if it.has_len { g.expr(it.len_expr) g.write(', ') @@ -4337,10 +4343,14 @@ fn (mut g Gen) array_init(it ast.ArrayInit) { g.write('0, ') } g.write('sizeof($elem_type_str), ') - if it.has_default || (it.has_len && it.elem_type == table.string_type) { - g.write('&_val_$it.pos.pos)') + if is_default_array { + g.write('_val_$it.pos.pos)') } else { - g.write('0)') + if it.has_default || (it.has_len && it.elem_type == table.string_type) { + g.write('&_val_$it.pos.pos)') + } else { + g.write('0)') + } } return }