From fc8ef0e70cdb75713db4cc149df78cc1fb5e95fe Mon Sep 17 00:00:00 2001 From: David Legrand Date: Thu, 7 May 2026 20:19:12 +0200 Subject: [PATCH] fmt: keep enum name when stringifying fixed-array size expressions (#27106) --- vlib/v/ast/types.v | 34 ++++++++++++++++--- .../struct_fixed_array_enum_cast_keep.vv | 16 +++++++++ 2 files changed, 46 insertions(+), 4 deletions(-) create mode 100644 vlib/v/fmt/tests/struct_fixed_array_enum_cast_keep.vv diff --git a/vlib/v/ast/types.v b/vlib/v/ast/types.v index c3eb64b1d..d6072d4aa 100644 --- a/vlib/v/ast/types.v +++ b/vlib/v/ast/types.v @@ -1700,11 +1700,9 @@ pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string] elem_str := t.type_to_str_using_aliases(info.elem_type, import_aliases) if info.size_expr is EmptyExpr { res = '[${info.size}]${elem_str}' - } else if info.size_expr is Ident { - size_str := t.shorten_user_defined_typenames(info.size_expr.name, import_aliases) - res = '[${size_str}]${elem_str}' } else { - res = '[${info.size_expr}]${elem_str}' + size_str := t.fixed_array_size_expr_to_str(info.size_expr, import_aliases) + res = '[${size_str}]${elem_str}' } } .chan { @@ -1858,6 +1856,34 @@ pub fn (t &Table) type_to_str_using_aliases(typ Type, import_aliases map[string] return res } +// fixed_array_size_expr_to_str renders a fixed-array size expression preserving +// fully-qualified enum names. The default `Expr.str()` drops the enum name on +// `EnumVal` (returning `.value`), which produces invalid output when the size +// is something like `int(TestEnum._max)` because the enum type cannot be +// inferred from context inside the array brackets. +fn (t &Table) fixed_array_size_expr_to_str(expr Expr, import_aliases map[string]string) string { + match expr { + CastExpr { + type_name := t.shorten_user_defined_typenames(t.type_to_str_using_aliases(expr.typ, + import_aliases), import_aliases) + return '${type_name}(${t.fixed_array_size_expr_to_str(expr.expr, import_aliases)})' + } + EnumVal { + if expr.enum_name != '' { + name := t.shorten_user_defined_typenames(expr.enum_name, import_aliases) + return '${name}.${expr.val}' + } + return '.${expr.val}' + } + Ident { + return t.shorten_user_defined_typenames(expr.name, import_aliases) + } + else { + return expr.str() + } + } +} + fn (t &Table) shorten_user_defined_typenames(original_name string, import_aliases map[string]string) string { if alias := import_aliases[original_name] { return alias diff --git a/vlib/v/fmt/tests/struct_fixed_array_enum_cast_keep.vv b/vlib/v/fmt/tests/struct_fixed_array_enum_cast_keep.vv new file mode 100644 index 000000000..5c645fd41 --- /dev/null +++ b/vlib/v/fmt/tests/struct_fixed_array_enum_cast_keep.vv @@ -0,0 +1,16 @@ +module main + +enum TestEnum { + one + two + _max +} + +struct Test1 { + list [int(TestEnum._max)]int +} + +fn main() { + t := Test1{} + assert t.list.len == int(TestEnum._max) +} -- 2.39.5