Skip to content

Commit

Permalink
checker: fix fn/method mut array args dimension mismatch check(fix vl…
Browse files Browse the repository at this point in the history
  • Loading branch information
shove70 committed Dec 14, 2023
1 parent 0b12d64 commit 3b4242f
Show file tree
Hide file tree
Showing 4 changed files with 49 additions and 35 deletions.
41 changes: 17 additions & 24 deletions vlib/v/ast/table.v
Original file line number Diff line number Diff line change
Expand Up @@ -1569,14 +1569,8 @@ pub fn (mut t Table) resolve_generic_to_concrete(generic_type Type, generic_name
}
match mut sym.info {
Array {
mut elem_type := sym.info.elem_type
mut elem_sym := t.sym(elem_type)
mut dims := 1
for mut elem_sym.info is Array {
elem_type = elem_sym.info.elem_type
elem_sym = t.sym(elem_type)
dims++
}
elem_type := sym.info.elem_type
dims := t.get_array_dims(sym.info)
if typ := t.resolve_generic_to_concrete(elem_type, generic_names, concrete_types) {
idx := t.find_or_register_array_with_dims(typ, dims)
if typ.has_flag(.generic) {
Expand Down Expand Up @@ -1782,14 +1776,7 @@ pub fn (mut t Table) generic_type_names(generic_type Type) []string {
}
match mut sym.info {
Array {
mut elem_type := sym.info.elem_type
mut elem_sym := t.sym(elem_type)
mut dims := 1
for mut elem_sym.info is Array {
elem_type = elem_sym.info.elem_type
elem_sym = t.sym(elem_type)
dims++
}
elem_type := sym.info.elem_type
names << t.generic_type_names(elem_type)
}
ArrayFixed {
Expand Down Expand Up @@ -1847,14 +1834,8 @@ pub fn (mut t Table) unwrap_generic_type(typ Type, generic_names []string, concr
ts := t.sym(typ)
match ts.info {
Array {
mut elem_type := ts.info.elem_type
mut elem_sym := t.sym(elem_type)
mut dims := 1
for mut elem_sym.info is Array {
elem_type = elem_sym.info.elem_type
elem_sym = t.sym(elem_type)
dims++
}
elem_type := ts.info.elem_type
dims := t.get_array_dims(ts.info)
unwrap_typ := t.unwrap_generic_type(elem_type, generic_names, concrete_types)
idx := t.find_or_register_array_with_dims(unwrap_typ, dims)
return new_type(idx).derive_add_muls(typ).clear_flag(.generic)
Expand Down Expand Up @@ -2502,3 +2483,15 @@ pub fn (t &Table) dependent_names_in_stmt(stmt Stmt) []string {
}
return names
}

pub fn (t &Table) get_array_dims(arr Array) int {
mut dims := 1
mut elem_type := arr.elem_type
mut elem_sym := t.sym(elem_type)
for mut elem_sym.info is Array {
dims++
elem_type = elem_sym.info.elem_type
elem_sym = t.sym(elem_type)
}
return dims
}
4 changes: 3 additions & 1 deletion vlib/v/checker/check_types.v
Original file line number Diff line number Diff line change
Expand Up @@ -293,7 +293,9 @@ fn (mut c Checker) check_expected_call_arg(got ast.Type, expected_ ast.Type, lan
if got.is_ptr() != expected.is_ptr()
|| !c.check_same_module(got, expected)
|| (!got.is_ptr() && !expected.is_ptr()
&& got_typ_sym.name != expected_typ_sym.name) {
&& got_typ_sym.name != expected_typ_sym.name)
|| (got_typ_sym.kind == .array && expected_typ_sym.kind == .array
&& c.table.get_array_dims(got_typ_sym.info as ast.Array) != c.table.get_array_dims(expected_typ_sym.info as ast.Array)) {
got_typ_str, expected_typ_str := c.get_string_names_of(got, expected)
return error('cannot use `${got_typ_str}` as `${expected_typ_str}`')
}
Expand Down
19 changes: 13 additions & 6 deletions vlib/v/checker/tests/fn_call_arg_array_mismatch_err.out
Original file line number Diff line number Diff line change
@@ -1,7 +1,14 @@
vlib/v/checker/tests/fn_call_arg_array_mismatch_err.vv:9:36: error: cannot use `string` as `array` in argument 2 to `os.write_file_array`
7 |
8 | fn main() {
9 | os.write_file_array(service_path, service_file) or {
vlib/v/checker/tests/fn_call_arg_array_mismatch_err.vv:7:36: error: cannot use `string` as `array` in argument 2 to `os.write_file_array`
5 |
6 | fn main() {
7 | os.write_file_array(service_path, service_file) or {
| ~~~~~~~~~~~~
10 | eprintln('Error: write file service')
11 | exit(1)
8 | eprintln('Error: write file service')
9 | exit(1)
vlib/v/checker/tests/fn_call_arg_array_mismatch_err.vv:16:10: error: cannot use `&[]int` as `&[][]int` in argument 1 to `bar`
14 | // dimension checking error when mut array is passed multiple times as args
15 | fn foo(mut arr []int) {
16 | bar(mut arr)
| ~~~
17 | }
18 |
20 changes: 16 additions & 4 deletions vlib/v/checker/tests/fn_call_arg_array_mismatch_err.vv
Original file line number Diff line number Diff line change
@@ -1,13 +1,25 @@
import os

const (
service_file = '[Unit]'
service_path = 'dockerman.service'
)
const service_file = '[Unit]'
const service_path = 'dockerman.service'

fn main() {
os.write_file_array(service_path, service_file) or {
eprintln('Error: write file service')
exit(1)
}
}

// for issue 20172
// dimension checking error when mut array is passed multiple times as args
fn foo(mut arr []int) {
bar(mut arr)
}

fn bar(mut arr [][]int) {
}

fn baz() {
mut arr := [1, 2, 3]
foo(mut arr)
}

0 comments on commit 3b4242f

Please sign in to comment.