From 5edc4902e2a607b14dc3c2bc75947a5ecf0816dc Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 05:34:46 +0300 Subject: [PATCH] cgen: fix fixed array with option dynamic elem not compiling (fixes #25460) --- vlib/v/gen/c/cgen.v | 8 ++++---- vlib/v/gen/c/testdata/fixed_arr_option_array.out | 1 + vlib/v/gen/c/testdata/fixed_arr_option_array.vv | 2 ++ vlib/v/tests/fixed_array_init_with_option_array_test.v | 5 +++++ 4 files changed, 12 insertions(+), 4 deletions(-) create mode 100644 vlib/v/gen/c/testdata/fixed_arr_option_array.out create mode 100644 vlib/v/gen/c/testdata/fixed_arr_option_array.vv diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index f079c6efb..524f4a130 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -9348,11 +9348,11 @@ fn (mut g Gen) ensure_fixed_array_option_definition(elem_type ast.Type) bool { return false } elem_sym := g.table.final_sym(elem_type.clear_option_and_result()) - if elem_sym.info !is ast.Struct && elem_sym.info !is ast.Interface - && elem_sym.info !is ast.SumType { + if elem_sym.is_builtin() { return false } styp, base := g.option_type_name(elem_type) + g.ensure_array_typedef(base) lock g.done_options { if base !in g.done_options { g.done_options << base @@ -9411,7 +9411,7 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) { ast.Struct { if !struct_names[name] && (!g.pref.skip_unused || sym.idx in g.table.used_features.used_syms) { - // generate field option types for fixed array of option struct/interface/sumtype + // generate field option types for fixed array of option non-builtin types // before the struct declaration opt_fields := sym.info.fields.filter(g.table.final_sym(it.typ).kind == .array_fixed) @@ -9542,7 +9542,7 @@ fn (mut g Gen) write_types(symbols []&ast.TypeSymbol) { g.type_definitions.writeln(def_str) } else if elem_sym.info !is ast.ArrayFixed || (elem_sym.info as ast.ArrayFixed).size > 0 { - // fixed array of option struct/interface/sumtype must be defined backwards + // fixed array of option non-builtin types must be defined backwards if g.ensure_fixed_array_option_definition(sym.info.elem_type) { g.type_definitions.writeln('typedef ${fixed_elem_name} ${styp} [${len}];') } else if !(resolved_elem_sym.info is ast.ArrayFixed diff --git a/vlib/v/gen/c/testdata/fixed_arr_option_array.out b/vlib/v/gen/c/testdata/fixed_arr_option_array.out new file mode 100644 index 000000000..ca1ab1bef --- /dev/null +++ b/vlib/v/gen/c/testdata/fixed_arr_option_array.out @@ -0,0 +1 @@ +[Option(none), Option(none), Option(none)] diff --git a/vlib/v/gen/c/testdata/fixed_arr_option_array.vv b/vlib/v/gen/c/testdata/fixed_arr_option_array.vv new file mode 100644 index 000000000..9632709ef --- /dev/null +++ b/vlib/v/gen/c/testdata/fixed_arr_option_array.vv @@ -0,0 +1,2 @@ +a := [3]?[]int{} +println(a) diff --git a/vlib/v/tests/fixed_array_init_with_option_array_test.v b/vlib/v/tests/fixed_array_init_with_option_array_test.v index f327ca678..c94efba1d 100644 --- a/vlib/v/tests/fixed_array_init_with_option_array_test.v +++ b/vlib/v/tests/fixed_array_init_with_option_array_test.v @@ -4,3 +4,8 @@ fn test_fixed_array_init_with_option_array() { z := [2][]?int{init: []?int{len: 3}} assert z.str() == '[[Option(none), Option(none), Option(none)], [Option(none), Option(none), Option(none)]]' } + +fn test_fixed_array_of_option_array() { + x := [3]?[]int{} + assert '${x}' == '[Option(none), Option(none), Option(none)]' +} -- 2.39.5