From 1b91ac324e7254fe19b25ff731f631795434c56a Mon Sep 17 00:00:00 2001 From: Sai Asish Y Date: Thu, 7 May 2026 11:42:39 -0700 Subject: [PATCH] checker: overwrite stale unresolved fixed-array sym for struct fields (fix #27078) (#27081) --- vlib/v/checker/struct.v | 11 +++++++++++ vlib/v/tests/project_issue_27078/main.v | 7 +++++++ vlib/v/tests/project_issue_27078/misc.v | 14 ++++++++++++++ vlib/v/tests/project_issue_27078/v.mod | 3 +++ vlib/v/tests/project_issue_27078_run_test.v | 9 +++++++++ 5 files changed, 44 insertions(+) create mode 100644 vlib/v/tests/project_issue_27078/main.v create mode 100644 vlib/v/tests/project_issue_27078/misc.v create mode 100644 vlib/v/tests/project_issue_27078/v.mod create mode 100644 vlib/v/tests/project_issue_27078_run_test.v diff --git a/vlib/v/checker/struct.v b/vlib/v/checker/struct.v index 2d8230002..94e71bb39 100644 --- a/vlib/v/checker/struct.v +++ b/vlib/v/checker/struct.v @@ -121,12 +121,23 @@ fn (mut c Checker) struct_decl(mut node ast.StructDecl) { sym := c.table.sym(field.typ) if sym.info is ast.ArrayFixed && c.array_fixed_has_unresolved_size(sym.info) { mut size_expr := unsafe { sym.info.size_expr } + old_typ := field.typ field.typ = c.eval_array_fixed_sizes(mut size_expr, 0, sym.info.elem_type) for mut symfield in struct_sym.info.fields { if symfield.name == field.name { symfield.typ = field.typ } } + // Overwrite the previously unresolved type symbol so that earlier + // expressions which captured its idx (e.g. IndexExpr.left_type from + // another file checked first) observe the resolved size. See #27078. + if old_typ.idx() != field.typ.idx() { + new_sym := c.table.sym(field.typ) + mut old_sym := c.table.type_symbols[old_typ.idx()] + old_sym.name = new_sym.name + old_sym.cname = new_sym.cname + old_sym.info = new_sym.info + } } } diff --git a/vlib/v/tests/project_issue_27078/main.v b/vlib/v/tests/project_issue_27078/main.v new file mode 100644 index 000000000..2046feab0 --- /dev/null +++ b/vlib/v/tests/project_issue_27078/main.v @@ -0,0 +1,7 @@ +module main + +fn main() { + mut t := TestStruct{} + t.list[TestEnum.one] = 1 + assert t.list[TestEnum.one] == 1 +} diff --git a/vlib/v/tests/project_issue_27078/misc.v b/vlib/v/tests/project_issue_27078/misc.v new file mode 100644 index 000000000..50260bdc6 --- /dev/null +++ b/vlib/v/tests/project_issue_27078/misc.v @@ -0,0 +1,14 @@ +module main + +enum TestEnum { + one + two + _max +} + +const te_max = int(TestEnum._max) + +struct TestStruct { +mut: + list [te_max]int +} diff --git a/vlib/v/tests/project_issue_27078/v.mod b/vlib/v/tests/project_issue_27078/v.mod new file mode 100644 index 000000000..92784c8f6 --- /dev/null +++ b/vlib/v/tests/project_issue_27078/v.mod @@ -0,0 +1,3 @@ +Module { + name: 'project_issue_27078' +} diff --git a/vlib/v/tests/project_issue_27078_run_test.v b/vlib/v/tests/project_issue_27078_run_test.v new file mode 100644 index 000000000..0719b9276 --- /dev/null +++ b/vlib/v/tests/project_issue_27078_run_test.v @@ -0,0 +1,9 @@ +import os + +const vexe = os.quoted_path(@VEXE) +const issue_27078_project = os.join_path(os.dir(@FILE), 'project_issue_27078') + +fn test_fixed_array_with_int_cast_enum_const_in_separate_file_runs() { + res := os.execute('${vexe} run ${os.quoted_path(issue_27078_project)}') + assert res.exit_code == 0, res.output +} -- 2.39.5