diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index fd7957299f..8dba4047f2 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -1284,7 +1284,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { table.FnType { ret_type = arg_sym.info.func.return_type } else { ret_type = arg_type } } - call_expr.return_type = c.table.find_or_register_array(ret_type, 1) + call_expr.return_type = c.table.find_or_register_array(ret_type) } else if method_name == 'filter' { // check fn c.check_map_and_filter(false, elem_typ, call_expr) @@ -1309,7 +1309,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { } 'keys' { info := left_type_sym.info as table.Map - typ := c.table.find_or_register_array(info.key_type, 1) + typ := c.table.find_or_register_array(info.key_type) ret_type = table.Type(typ) } else {} @@ -1492,7 +1492,7 @@ pub fn (mut c Checker) call_method(mut call_expr ast.CallExpr) table.Type { elem_info := return_sym.info as table.Array elem_sym := c.table.get_type_symbol(elem_info.elem_type) if elem_sym.name == 'T' { - idx := c.table.find_or_register_array(call_expr.generic_type, 1) + idx := c.table.find_or_register_array(call_expr.generic_type) return table.new_type(idx) } } @@ -1825,7 +1825,7 @@ pub fn (mut c Checker) call_fn(mut call_expr ast.CallExpr) table.Type { break } } - idx := c.table.find_or_register_array(call_expr.generic_type, dims) + idx := c.table.find_or_register_array_with_dims(call_expr.generic_type, dims) typ := table.new_type(idx) call_expr.return_type = typ return typ @@ -2733,11 +2733,10 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { } } if array_init.is_fixed { - idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len, - 1) + idx := c.table.find_or_register_array_fixed(elem_type, array_init.exprs.len) array_init.typ = table.new_type(idx) } else { - idx := c.table.find_or_register_array(elem_type, 1) + idx := c.table.find_or_register_array(elem_type) array_init.typ = table.new_type(idx) } array_init.elem_type = elem_type @@ -2764,8 +2763,7 @@ pub fn (mut c Checker) array_init(mut array_init ast.ArrayInit) table.Type { c.error('expecting `int` for fixed size', array_init.pos) } } - idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size, - 1) + idx := c.table.find_or_register_array_fixed(array_init.elem_type, fixed_size) array_type := table.new_type(idx) array_init.typ = array_type if array_init.has_default { @@ -4749,7 +4747,7 @@ pub fn (mut c Checker) index_expr(mut node ast.IndexExpr) table.Type { // fixed_array[1..2] => array if typ_sym.kind == .array_fixed { elem_type := c.table.value_type(typ) - idx := c.table.find_or_register_array(elem_type, 1) + idx := c.table.find_or_register_array(elem_type) return table.new_type(idx) } return typ.set_nr_muls(0) diff --git a/vlib/v/parser/containers.v b/vlib/v/parser/containers.v index eb458f92ce..e8c486e791 100644 --- a/vlib/v/parser/containers.v +++ b/vlib/v/parser/containers.v @@ -32,7 +32,7 @@ fn (mut p Parser) array_init() ast.ArrayInit { elem_type = p.parse_type() // this is set here because it's a known type, others could be the // result of expr so we do those in checker - idx := p.table.find_or_register_array(elem_type, 1) + idx := p.table.find_or_register_array(elem_type) array_type = table.new_type(idx) has_type = true } diff --git a/vlib/v/parser/fn.v b/vlib/v/parser/fn.v index 66aca48df1..e8158ad1f6 100644 --- a/vlib/v/parser/fn.v +++ b/vlib/v/parser/fn.v @@ -567,7 +567,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } } if is_variadic { - arg_type = table.new_type(p.table.find_or_register_array(arg_type, 1)).set_flag(.variadic) + arg_type = table.new_type(p.table.find_or_register_array(arg_type)).set_flag(.variadic) } if p.tok.kind == .eof { p.error_with_pos('expecting `)`', p.prev_tok.position()) @@ -655,7 +655,7 @@ fn (mut p Parser) fn_args() ([]table.Param, bool, bool) { } } if is_variadic { - typ = table.new_type(p.table.find_or_register_array(typ, 1)).set_flag(.variadic) + typ = table.new_type(p.table.find_or_register_array(typ)).set_flag(.variadic) } for i, arg_name in arg_names { args << table.Param{ diff --git a/vlib/v/parser/parse_type.v b/vlib/v/parser/parse_type.v index 390f3c2f1f..df41952a38 100644 --- a/vlib/v/parser/parse_type.v +++ b/vlib/v/parser/parse_type.v @@ -19,7 +19,7 @@ pub fn (mut p Parser) parse_array_type() table.Type { return 0 } // sym := p.table.get_type_symbol(elem_type) - idx := p.table.find_or_register_array_fixed(elem_type, size, 1) + idx := p.table.find_or_register_array_fixed(elem_type, size) return table.new_type(idx) } // array @@ -37,7 +37,7 @@ pub fn (mut p Parser) parse_array_type() table.Type { p.check(.rsbr) nr_dims++ } - idx := p.table.find_or_register_array(elem_type, nr_dims) + idx := p.table.find_or_register_array_with_dims(elem_type, nr_dims) return table.new_type(idx) } @@ -121,7 +121,7 @@ pub fn (mut p Parser) parse_fn_type(name string) table.Type { is_variadic: is_variadic return_type: return_type } - // MapFooFn typedefs are manually added in cheaders.v + // MapFooFn typedefs are manually added in cheaders.v // because typedefs get generated after the map struct is generated has_decl := p.builtin_mod && name.starts_with('Map') && name.ends_with('Fn') idx := p.table.find_or_register_fn_type(p.mod, func, false, has_decl) diff --git a/vlib/v/parser/sql.v b/vlib/v/parser/sql.v index 646d5bbe44..08182739db 100644 --- a/vlib/v/parser/sql.v +++ b/vlib/v/parser/sql.v @@ -77,7 +77,7 @@ fn (mut p Parser) sql_expr() ast.Expr { } if !query_one && !is_count { // return an array - typ = table.new_type(p.table.find_or_register_array(table_type, 1)) + typ = table.new_type(p.table.find_or_register_array(table_type)) } else if !is_count { // return a single object // TODO optional diff --git a/vlib/v/table/table.v b/vlib/v/table/table.v index 626ded342f..659a7215d7 100644 --- a/vlib/v/table/table.v +++ b/vlib/v/table/table.v @@ -392,23 +392,19 @@ pub fn (t &Table) known_type(name string) bool { // array_source_name generates the original name for the v source. // e. g. []int [inline] -pub fn (t &Table) array_name(elem_type Type, nr_dims int) string { +pub fn (t &Table) array_name(elem_type Type) string { elem_type_sym := t.get_type_symbol(elem_type) ptr := if elem_type.is_ptr() { '&'.repeat(elem_type.nr_muls()) } else { '' } - dims := '[]'.repeat(nr_dims) - return '$dims$ptr$elem_type_sym.name' + return '[]$ptr$elem_type_sym.name' } [inline] -pub fn (t &Table) array_cname(elem_type Type, nr_dims int) string { +pub fn (t &Table) array_cname(elem_type Type) string { elem_type_sym := t.get_type_symbol(elem_type) mut res := '' if elem_type.is_ptr() { res = '_ptr'.repeat(elem_type.nr_muls()) } - if nr_dims > 1 { - res += '_${nr_dims}d' - } return 'array_$elem_type_sym.cname' + res } @@ -422,15 +418,12 @@ pub fn (t &Table) array_fixed_name(elem_type Type, size int) string { } [inline] -pub fn (t &Table) array_fixed_cname(elem_type Type, size int, nr_dims int) string { +pub fn (t &Table) array_fixed_cname(elem_type Type, size int) string { elem_type_sym := t.get_type_symbol(elem_type) mut res := '' if elem_type.is_ptr() { res = '_ptr' } - if nr_dims > 1 { - res += '_${nr_dims}d' - } return 'array_fixed_${elem_type_sym.cname}_$size' + res } @@ -521,9 +514,9 @@ pub fn (mut t Table) find_or_register_map(key_type Type, value_type Type) int { return t.register_type_symbol(map_typ) } -pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int) int { - name := t.array_name(elem_type, nr_dims) - cname := t.array_cname(elem_type, nr_dims) +pub fn (mut t Table) find_or_register_array(elem_type Type) int { + name := t.array_name(elem_type) + cname := t.array_cname(elem_type) // existing existing_idx := t.type_idxs[name] if existing_idx > 0 { @@ -537,15 +530,22 @@ pub fn (mut t Table) find_or_register_array(elem_type Type, nr_dims int) int { cname: cname info: Array{ elem_type: elem_type - nr_dims: nr_dims } } return t.register_type_symbol(array_type) } -pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int, nr_dims int) int { +pub fn (mut t Table) find_or_register_array_with_dims(elem_type Type, nr_dims int) int { + return if nr_dims == 1 { + t.find_or_register_array(elem_type) + } else { + t.find_or_register_array(t.find_or_register_array_with_dims(elem_type, nr_dims - 1)) + } +} + +pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int) int { name := t.array_fixed_name(elem_type, size) - cname := t.array_fixed_cname(elem_type, size, nr_dims) + cname := t.array_fixed_cname(elem_type, size) // existing existing_idx := t.type_idxs[name] if existing_idx > 0 { @@ -559,7 +559,6 @@ pub fn (mut t Table) find_or_register_array_fixed(elem_type Type, size int, nr_d info: ArrayFixed{ elem_type: elem_type size: size - nr_dims: nr_dims } } return t.register_type_symbol(array_fixed_type) diff --git a/vlib/v/table/types.v b/vlib/v/table/types.v index a73bbaecb8..864cb2ad8b 100644 --- a/vlib/v/table/types.v +++ b/vlib/v/table/types.v @@ -688,8 +688,7 @@ pub mut: pub struct ArrayFixed { pub: - nr_dims int - size int + size int pub mut: elem_type Type } diff --git a/vlib/v/tests/array_to_string_test.v b/vlib/v/tests/array_to_string_test.v index 004272861a..9efbbfee88 100644 --- a/vlib/v/tests/array_to_string_test.v +++ b/vlib/v/tests/array_to_string_test.v @@ -1,3 +1,7 @@ +fn array_array_array(len int, value T) [][][]T { + return [][][]T{len: len, init: [][]T{len: len, init: []T{len: len, init: value}}} +} + fn test_array_to_string_conversion() { a := ['1', '2', '3', '4'] assert a.str() == "['1', '2', '3', '4']" @@ -16,6 +20,10 @@ fn test_array_to_string_conversion() { f := [byte(66), 32, 126, 10, 13, 5, 18, 127, 255] assert f.str() == '[B, , ~, `\\n`, `\\r`, 0x05, 0x12, 0x7f, 0xff]' + + // https://github.com/vlang/v/issues/8036 + g := array_array_array(2, 2) + assert g.str() == '[[[2, 2], [2, 2]], [[2, 2], [2, 2]]]' } fn test_interpolation_array_to_string() {