diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index 59a19cd698..a6b36b873f 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -138,6 +138,11 @@ pub fn (mut b Builder) middle_stages() ! { if b.checker.should_abort { return error('too many errors/warnings/notices') } + if b.checker.unresolved_return_size.len > 0 { + util.timing_start('Checker.update_unresolved_sizes') + b.checker.update_unresolved_return_sizes() + util.timing_measure('Checker.update_unresolved_sizes') + } if b.pref.check_only { return error_with_code('stop_after_checker', 8001) } diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 0c2bcaa97c..327e2442ef 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -74,20 +74,21 @@ pub mut: in_for_count int // if checker is currently in a for loop returns bool scope_returns bool - is_builtin_mod bool // true inside the 'builtin', 'os' or 'strconv' modules; TODO: remove the need for special casing this - is_just_builtin_mod bool // true only inside 'builtin' - is_generated bool // true for `@[generated] module xyz` .v files - inside_recheck bool // true when rechecking rhs assign statement - inside_unsafe bool // true inside `unsafe {}` blocks - inside_const bool // true inside `const ( ... )` blocks - inside_anon_fn bool // true inside `fn() { ... }()` - inside_lambda bool // true inside `|...| ...` - inside_ref_lit bool // true inside `a := &something` - inside_defer bool // true inside `defer {}` blocks - inside_return bool // true inside `return ...` blocks - inside_fn_arg bool // `a`, `b` in `a.f(b)` - inside_ct_attr bool // true inside `[if expr]` - inside_x_is_type bool // true inside the Type expression of `if x is Type {` + is_builtin_mod bool // true inside the 'builtin', 'os' or 'strconv' modules; TODO: remove the need for special casing this + is_just_builtin_mod bool // true only inside 'builtin' + is_generated bool // true for `@[generated] module xyz` .v files + unresolved_return_size []&ast.FnDecl // funcs with unresolved array fixed size e.g. fn func() [const1]int + inside_recheck bool // true when rechecking rhs assign statement + inside_unsafe bool // true inside `unsafe {}` blocks + inside_const bool // true inside `const ( ... )` blocks + inside_anon_fn bool // true inside `fn() { ... }()` + inside_lambda bool // true inside `|...| ...` + inside_ref_lit bool // true inside `a := &something` + inside_defer bool // true inside `defer {}` blocks + inside_return bool // true inside `return ...` blocks + inside_fn_arg bool // `a`, `b` in `a.f(b)` + inside_ct_attr bool // true inside `[if expr]` + inside_x_is_type bool // true inside the Type expression of `if x is Type {` inside_generic_struct_init bool inside_integer_literal_cast bool // true inside `int(123)` cur_struct_generic_types []ast.Type @@ -5551,3 +5552,13 @@ fn (c &Checker) check_import_sym_conflict(ident string) bool { } return false } + +pub fn (mut c Checker) update_unresolved_return_sizes() { + for mut fun in c.unresolved_return_size { + ret_sym := c.table.sym(fun.return_type) + if ret_sym.info is ast.ArrayFixed && c.array_fixed_has_unresolved_size(ret_sym.info) { + mut size_expr := ret_sym.info.size_expr + fun.return_type = c.eval_array_fixed_sizes(mut size_expr, 0, ret_sym.info.elem_type) + } + } +} diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index 572557835e..2814c7bac8 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -170,6 +170,10 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) { c.warn('byte is deprecated, use u8 instead', node.return_type_pos) } } + if return_sym.info is ast.ArrayFixed && c.array_fixed_has_unresolved_size(return_sym.info) { + c.unresolved_return_size << node + } + final_return_sym := c.table.final_sym(node.return_type) if final_return_sym.info is ast.MultiReturn { for multi_type in final_return_sym.info.types { diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index ca4b4e1328..a702a28a40 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -1877,6 +1877,10 @@ pub fn (mut g Gen) write_array_fixed_return_types() { for sym in fixed_arr_rets { info := sym.info as ast.ArrayFixed + if info.size <= 0 { + // unresolved sizes e.g. [unknown_const]int + continue + } mut fixed_elem_name := g.styp(info.elem_type.set_nr_muls(0)) if info.elem_type.is_ptr() { fixed_elem_name += '*'.repeat(info.elem_type.nr_muls()) diff --git a/vlib/v/tests/consts/const_fixed_array_return_unresolved_test.v b/vlib/v/tests/consts/const_fixed_array_return_unresolved_test.v new file mode 100644 index 0000000000..af726e0582 --- /dev/null +++ b/vlib/v/tests/consts/const_fixed_array_return_unresolved_test.v @@ -0,0 +1,15 @@ +fn get_chunkmap_at_coords(mapp []Chunk) [chunk_size][chunk_size]u64 { + return mapp[0].id_map +} + +const chunk_size = 100 + +struct Chunk { + id_map [chunk_size][chunk_size]u64 +} + +fn test_main() { + t := Chunk{} + assert t.id_map[0].len == 100 + assert t.id_map.len == 100 +}