diff --git a/vlib/v/checker/check_types.v b/vlib/v/checker/check_types.v index 8d9b526f2e2466..7a669b161b7aba 100644 --- a/vlib/v/checker/check_types.v +++ b/vlib/v/checker/check_types.v @@ -453,6 +453,21 @@ fn (mut c Checker) check_basic(got ast.Type, expected ast.Type) bool { if got == ast.float_literal_type && expected_nonflagged.is_float() { return true } + // decode and check array to aliased array type + if got_sym.kind == .array && exp_sym.info is ast.Array { + exp_elem_sym := c.table.sym(exp_sym.info.elem_type) + if exp_elem_sym.info is ast.Alias { + parent_elem_sym := c.table.sym(exp_elem_sym.info.parent_type) + if parent_elem_sym.info is ast.Array { + array_info := parent_elem_sym.array_info() + elem_type := c.table.find_or_register_array_with_dims(array_info.elem_type, + array_info.nr_dims + exp_sym.info.nr_dims) + if c.table.type_to_str(got) == c.table.type_to_str(elem_type) { + return true + } + } + } + } return false } diff --git a/vlib/v/checker/containers.v b/vlib/v/checker/containers.v index c26dddca98d54f..73e1ff0b5306cc 100644 --- a/vlib/v/checker/containers.v +++ b/vlib/v/checker/containers.v @@ -7,7 +7,7 @@ import v.token fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { mut elem_type := ast.void_type - unwrap_elem_type := c.unwrap_generic(node.elem_type) + mut unwrap_elem_type := c.unwrap_generic(node.elem_type) if c.pref.warn_about_allocs { c.warn_alloc('array initialization', node.pos) } @@ -60,6 +60,15 @@ fn (mut c Checker) array_init(mut node ast.ArrayInit) ast.Type { if elem_sym.name == 'byte' { c.warn('byte is deprecated, use u8 instead', node.elem_type_pos) } + parent_sym := c.table.sym(elem_sym.info.parent_type) + // check array to aliased array type + if parent_sym.info is ast.Array { + node.alias_type = c.table.find_or_register_array(unwrap_elem_type) + node.elem_type = c.table.find_or_register_array_with_dims(parent_sym.info.elem_type, + parent_sym.info.nr_dims) + unwrap_elem_type = node.elem_type + node.typ = c.table.find_or_register_array(node.elem_type) + } } else {} } diff --git a/vlib/v/tests/aliases/array_alias_test.v b/vlib/v/tests/aliases/array_alias_test.v new file mode 100644 index 00000000000000..9eaed355b370c3 --- /dev/null +++ b/vlib/v/tests/aliases/array_alias_test.v @@ -0,0 +1,65 @@ +module main + +type OneD = []Thing + +struct Thing { + item int +} + +fn good() [][]Thing { + println('start good()') + mut two_d := [][]Thing{} + mut one_d := []Thing{} + one_d << Thing{1} + one_d << Thing{2} + two_d << one_d + assert two_d.len == 1, 'two_d length not 1' + for i, one in two_d { + for j, item in one { + println('two_d[${i}][${j}]=${item}') + assert item == Thing{j + 1} + } + } + println('end good()') + return two_d +} + +fn bad() []OneD { + println('start bad()') + mut two_d := []OneD{} + mut one_d := OneD{} + one_d << Thing{1} + one_d << Thing{2} + assert one_d.len == 2, 'one_d length not 2' + assert one_d[0] == Thing{1}, 'one_d[0] not 1' + assert one_d[1] == Thing{2}, 'one_d[1] not 2' + two_d << one_d + assert two_d.len == 1, 'two_d length not 1' + for i, one in two_d { + for j, item in one { + println('two_d[${i}][${j}]=${item}') + assert item == Thing{j + 1} + } + } + println('end bad()') + return two_d +} + +fn test_main() { + good_two_d := good() + assert good_two_d.len == 1, 'good_two_d length not 1' + for i, one_d in good_two_d { + for j, item in one_d { + println('good_two_d[${i}][${j}]=${item}') + assert item == Thing{j + 1} + } + } + bad_two_d := bad() + assert bad_two_d.len == 1, 'bad_two_d length not 1' + for i, one_d in bad_two_d { + for j, item in one_d { + println('bad_two_d[${i}][${j}]=${item}') + assert item == Thing{j + 1} + } + } +}