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

checker: fix alias to fixed array w/ size defined by constant #23357

Merged
merged 4 commits into from
Jan 4, 2025
Merged
Show file tree
Hide file tree
Changes from 1 commit
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
13 changes: 7 additions & 6 deletions vlib/v/ast/ast.v
Original file line number Diff line number Diff line change
Expand Up @@ -1452,13 +1452,14 @@ pub:

pub struct AliasTypeDecl {
pub:
name string
is_pub bool
typ Type
name string
is_pub bool
typ Type
pos token.Pos
type_pos token.Pos
comments []Comment
pub mut:
parent_type Type
pos token.Pos
type_pos token.Pos
comments []Comment
}

// SumTypeDecl is the ast node for `type MySumType = string | int`
Expand Down
10 changes: 5 additions & 5 deletions vlib/v/ast/types.v
Original file line number Diff line number Diff line change
Expand Up @@ -96,9 +96,8 @@ pub fn pref_arch_to_table_language(pref_arch pref.Arch) Language {
// See also: Table.sym.
@[minify]
pub struct TypeSymbol {
pub:
parent_idx int
pub mut:
parent_idx int
info TypeInfo
kind Kind
name string // the internal & source name of the type, i.e. `[5]int`.
Expand Down Expand Up @@ -211,10 +210,11 @@ pub:

@[minify]
pub struct Alias {
pub:
pub mut:
parent_type Type
language Language
is_import bool
pub:
language Language
is_import bool
}

pub struct Aggregate {
Expand Down
8 changes: 4 additions & 4 deletions vlib/v/builder/builder.v
Original file line number Diff line number Diff line change
Expand Up @@ -138,10 +138,10 @@ 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.checker.unresolved_fixed_sizes.len > 0 {
util.timing_start('Checker.update_unresolved_fixed_sizes')
b.checker.update_unresolved_fixed_sizes()
util.timing_measure('Checker.update_unresolved_fixed_sizes')
}
if b.pref.check_only {
return error_with_code('stop_after_checker', 8001)
Expand Down
69 changes: 47 additions & 22 deletions vlib/v/checker/checker.v
Original file line number Diff line number Diff line change
Expand Up @@ -74,21 +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
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 {`
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_fixed_sizes []&ast.Stmt // 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 @@ -613,7 +613,11 @@ fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) {
'array')
}
.array_fixed {
c.check_alias_vs_element_type_of_parent(node, (parent_typ_sym.info as ast.ArrayFixed).elem_type,
array_fixed_info := parent_typ_sym.info as ast.ArrayFixed
if c.array_fixed_has_unresolved_size(array_fixed_info) {
c.unresolved_fixed_sizes << unsafe { &ast.TypeDecl(&node) }
felipensp marked this conversation as resolved.
Show resolved Hide resolved
}
c.check_alias_vs_element_type_of_parent(node, array_fixed_info.elem_type,
'fixed array')
}
.map {
Expand Down Expand Up @@ -5554,12 +5558,33 @@ 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)
// update_unresolved_fixed_sizes updates the unresolved type symbols for array fixed return type and alias type
pub fn (mut c Checker) update_unresolved_fixed_sizes() {
for mut stmt in c.unresolved_fixed_sizes {
if mut stmt is ast.FnDecl { // return types
ret_sym := c.table.sym(stmt.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
stmt.return_type = c.eval_array_fixed_sizes(mut size_expr, 0, ret_sym.info.elem_type)
}
} else if mut stmt is ast.TypeDecl { // alias
mut alias_decl := stmt
if mut alias_decl is ast.AliasTypeDecl {
alias_sym := c.table.sym(alias_decl.parent_type)
if alias_sym.info is ast.ArrayFixed
&& c.array_fixed_has_unresolved_size(alias_sym.info) {
mut size_expr := alias_sym.info.size_expr
alias_decl.parent_type = c.eval_array_fixed_sizes(mut size_expr, 0,
alias_sym.info.elem_type)

// overwriting current alias type
mut typ_sym := c.table.type_symbols[alias_decl.typ.idx()]
typ_sym.parent_idx = alias_decl.parent_type.idx()
if mut typ_sym.info is ast.Alias {
typ_sym.info.parent_type = alias_decl.parent_type
}
}
}
}
}
}
2 changes: 1 addition & 1 deletion vlib/v/checker/fn.v
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ fn (mut c Checker) fn_decl(mut node ast.FnDecl) {
}
}
if return_sym.info is ast.ArrayFixed && c.array_fixed_has_unresolved_size(return_sym.info) {
c.unresolved_return_size << node
c.unresolved_fixed_sizes << node
}

final_return_sym := c.table.final_sym(node.return_type)
Expand Down
20 changes: 20 additions & 0 deletions vlib/v/tests/aliases/alias_const_array_fixed_test.v
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
module main

const image_width = 800
const image_height = 400

struct Colour {
r u8
g u8
b u8
}

const buffer_size = image_width * image_height * sizeof[Colour]()

type ImageBuffer = [buffer_size]Colour

fn test_main() {
println('Hello World!')
t := ImageBuffer{}
assert t.len == buffer_size
}
Loading