From 4207862223b10e7e1dc40551ee03a5d68cbdd881 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Fri, 3 Jan 2025 15:52:47 -0300 Subject: [PATCH 1/4] fix --- vlib/v/ast/ast.v | 13 ++-- vlib/v/ast/types.v | 10 +-- vlib/v/builder/builder.v | 8 +-- vlib/v/checker/checker.v | 69 +++++++++++++------ vlib/v/checker/fn.v | 2 +- .../aliases/alias_const_array_fixed_test.v | 20 ++++++ 6 files changed, 84 insertions(+), 38 deletions(-) create mode 100644 vlib/v/tests/aliases/alias_const_array_fixed_test.v diff --git a/vlib/v/ast/ast.v b/vlib/v/ast/ast.v index 483f75578a3bdf..0b0be0fe4414b0 100644 --- a/vlib/v/ast/ast.v +++ b/vlib/v/ast/ast.v @@ -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` diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index 30659ff7bdfa1e..8d989b79a8d134 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -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`. @@ -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 { diff --git a/vlib/v/builder/builder.v b/vlib/v/builder/builder.v index a6b36b873fce21..d58cd7d3e95667 100644 --- a/vlib/v/builder/builder.v +++ b/vlib/v/builder/builder.v @@ -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) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index a6f1d7571e1bff..ce9f07e3da554c 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -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 @@ -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) } + } + c.check_alias_vs_element_type_of_parent(node, array_fixed_info.elem_type, 'fixed array') } .map { @@ -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 + } + } + } } } } diff --git a/vlib/v/checker/fn.v b/vlib/v/checker/fn.v index bcda8c76ca5dbb..65a99cc1b098ab 100644 --- a/vlib/v/checker/fn.v +++ b/vlib/v/checker/fn.v @@ -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) diff --git a/vlib/v/tests/aliases/alias_const_array_fixed_test.v b/vlib/v/tests/aliases/alias_const_array_fixed_test.v new file mode 100644 index 00000000000000..f310a011ffeb63 --- /dev/null +++ b/vlib/v/tests/aliases/alias_const_array_fixed_test.v @@ -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 +} From 22134eb8af6ad0bfcb67025f9c69edb748844b4d Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Fri, 3 Jan 2025 20:25:48 -0300 Subject: [PATCH 2/4] fix --- vlib/v/checker/checker.v | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index ce9f07e3da554c..55f3845443fac7 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -520,21 +520,21 @@ fn (mut c Checker) check_valid_pascal_case(name string, identifier string, pos t } } -fn (mut c Checker) type_decl(node ast.TypeDecl) { +fn (mut c Checker) type_decl(mut node ast.TypeDecl) { if node.typ == ast.invalid_type && (node is ast.AliasTypeDecl || node is ast.SumTypeDecl) { typ_desc := if node is ast.AliasTypeDecl { 'alias' } else { 'sum type' } c.error('cannot register ${typ_desc} `${node.name}`, another type with this name exists', node.pos) return } - match node { - ast.AliasTypeDecl { c.alias_type_decl(node) } - ast.FnTypeDecl { c.fn_type_decl(node) } - ast.SumTypeDecl { c.sum_type_decl(node) } + match mut node { + ast.AliasTypeDecl { c.alias_type_decl(mut node) } + ast.FnTypeDecl { c.fn_type_decl(mut node) } + ast.SumTypeDecl { c.sum_type_decl(mut node) } } } -fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) { +fn (mut c Checker) alias_type_decl(mut node ast.AliasTypeDecl) { if c.file.mod.name != 'builtin' && !node.name.starts_with('C.') { c.check_valid_pascal_case(node.name, 'type alias', node.pos) } @@ -615,7 +615,7 @@ fn (mut c Checker) alias_type_decl(node ast.AliasTypeDecl) { .array_fixed { 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) } + c.unresolved_fixed_sizes << unsafe { &ast.TypeDecl(node) } } c.check_alias_vs_element_type_of_parent(node, array_fixed_info.elem_type, 'fixed array') @@ -669,7 +669,7 @@ fn (mut c Checker) check_any_type(typ ast.Type, sym &ast.TypeSymbol, pos token.P } } -fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) { +fn (mut c Checker) fn_type_decl(mut node ast.FnTypeDecl) { c.check_valid_pascal_case(node.name, 'fn type', node.pos) typ_sym := c.table.sym(node.typ) fn_typ_info := typ_sym.info as ast.FnType @@ -690,7 +690,7 @@ fn (mut c Checker) fn_type_decl(node ast.FnTypeDecl) { } } -fn (mut c Checker) sum_type_decl(node ast.SumTypeDecl) { +fn (mut c Checker) sum_type_decl(mut node ast.SumTypeDecl) { c.check_valid_pascal_case(node.name, 'sum type', node.pos) mut names_used := []string{} for variant in node.variants { @@ -2380,7 +2380,7 @@ fn (mut c Checker) stmt(mut node ast.Stmt) { c.struct_decl(mut node) } ast.TypeDecl { - c.type_decl(node) + c.type_decl(mut node) } } } From 7d84ef28571b1d8dfb2d8cac247137dd37d17d25 Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Fri, 3 Jan 2025 20:28:21 -0300 Subject: [PATCH 3/4] fix --- vlib/v/checker/checker.v | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/vlib/v/checker/checker.v b/vlib/v/checker/checker.v index 55f3845443fac7..829c9fabb0bf9a 100644 --- a/vlib/v/checker/checker.v +++ b/vlib/v/checker/checker.v @@ -615,7 +615,7 @@ fn (mut c Checker) alias_type_decl(mut node ast.AliasTypeDecl) { .array_fixed { 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) } + c.unresolved_fixed_sizes << &ast.TypeDecl(node) } c.check_alias_vs_element_type_of_parent(node, array_fixed_info.elem_type, 'fixed array') From 6be44320e969a07a2b0eff3a1551a5b2121645bc Mon Sep 17 00:00:00 2001 From: Felipe Pena Date: Fri, 3 Jan 2025 20:29:58 -0300 Subject: [PATCH 4/4] fix --- vlib/v/tests/aliases/alias_const_array_fixed_test.v | 1 - 1 file changed, 1 deletion(-) diff --git a/vlib/v/tests/aliases/alias_const_array_fixed_test.v b/vlib/v/tests/aliases/alias_const_array_fixed_test.v index f310a011ffeb63..4bfacb21664834 100644 --- a/vlib/v/tests/aliases/alias_const_array_fixed_test.v +++ b/vlib/v/tests/aliases/alias_const_array_fixed_test.v @@ -14,7 +14,6 @@ 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 }