Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v: fix return array fixed with unresolved const as size #23279

Merged
merged 5 commits into from
Dec 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions vlib/v/builder/builder.v
Original file line number Diff line number Diff line change
Expand Up @@ -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')
spytheman marked this conversation as resolved.
Show resolved Hide resolved
}
if b.pref.check_only {
return error_with_code('stop_after_checker', 8001)
}
Expand Down
39 changes: 25 additions & 14 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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)
}
}
}
4 changes: 4 additions & 0 deletions vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
4 changes: 4 additions & 0 deletions vlib/v/gen/c/cgen.v
Original file line number Diff line number Diff line change
Expand Up @@ -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())
Expand Down
15 changes: 15 additions & 0 deletions vlib/v/tests/consts/const_fixed_array_return_unresolved_test.v
Original file line number Diff line number Diff line change
@@ -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
}
Loading