Skip to content

Commit

Permalink
parser, checker: fix array alias (#22175)
Browse files Browse the repository at this point in the history
  • Loading branch information
felipensp authored Sep 10, 2024
1 parent f890566 commit 33ff7c1
Show file tree
Hide file tree
Showing 3 changed files with 90 additions and 1 deletion.
15 changes: 15 additions & 0 deletions vlib/v/checker/check_types.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
}

Expand Down
11 changes: 10 additions & 1 deletion vlib/v/checker/containers.v
Original file line number Diff line number Diff line change
Expand Up @@ -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)
}
Expand Down Expand Up @@ -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 {}
}
Expand Down
65 changes: 65 additions & 0 deletions vlib/v/tests/aliases/array_alias_test.v
Original file line number Diff line number Diff line change
@@ -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}
}
}
}

0 comments on commit 33ff7c1

Please sign in to comment.