From e2824b7ffa285ffb6952e0c5fad5a7f8dd3c69b5 Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Wed, 15 Apr 2026 01:32:10 +0300 Subject: [PATCH] cgen: fix error related to empty interface (fixes #25872) --- vlib/v/gen/c/cgen.v | 133 +++++++++--------- .../main_test.v | 42 ++++++ .../mod/mod.v | 3 + 3 files changed, 112 insertions(+), 66 deletions(-) create mode 100644 vlib/v/tests/modules/interface_array_concat_from_another_module/main_test.v create mode 100644 vlib/v/tests/modules/interface_array_concat_from_another_module/mod/mod.v diff --git a/vlib/v/gen/c/cgen.v b/vlib/v/gen/c/cgen.v index a71ef5922..05903b220 100644 --- a/vlib/v/gen/c/cgen.v +++ b/vlib/v/gen/c/cgen.v @@ -942,75 +942,76 @@ fn cgen_process_one_file_cb(mut p pool.PoolProcessor, idx int, wid int) voidptr } mut global_g := unsafe { &Gen(p.get_shared_context()) } mut g := &Gen{ - fid: idx - tid: v_gettid().hex() - file: file - out: strings.new_builder(512000) - cheaders: strings.new_builder(15000) - includes: strings.new_builder(100) - typedefs: strings.new_builder(100) - type_definitions: strings.new_builder(100) - sort_fn_definitions: strings.new_builder(100) - alias_definitions: strings.new_builder(100) - definitions: strings.new_builder(100) - gowrappers: strings.new_builder(100) - waiter_fn_definitions: strings.new_builder(100) - auto_str_funcs: strings.new_builder(100) - comptime_definitions: strings.new_builder(100) - pcs_declarations: strings.new_builder(100) - cov_declarations: strings.new_builder(100) - hotcode_definitions: strings.new_builder(100) - embedded_data: strings.new_builder(1000) - out_options_forward: strings.new_builder(100) - out_options: strings.new_builder(100) - out_results_forward: strings.new_builder(100) - out_results: strings.new_builder(100) - shared_types: strings.new_builder(100) - shared_functions: strings.new_builder(100) - channel_definitions: strings.new_builder(100) - thread_definitions: strings.new_builder(100) - json_forward_decls: strings.new_builder(100) - enum_typedefs: strings.new_builder(100) - sql_buf: strings.new_builder(100) - cleanup: strings.new_builder(100) - table: global_g.table - pref: global_g.pref - fn_decl: unsafe { nil } - anon_fn: unsafe { nil } - indent: -1 - module_built: global_g.module_built - static_non_parallel: global_g.static_non_parallel - static_modifier: global_g.static_modifier - timers: util.new_timers( + fid: idx + tid: v_gettid().hex() + file: file + out: strings.new_builder(512000) + cheaders: strings.new_builder(15000) + includes: strings.new_builder(100) + typedefs: strings.new_builder(100) + type_definitions: strings.new_builder(100) + sort_fn_definitions: strings.new_builder(100) + alias_definitions: strings.new_builder(100) + definitions: strings.new_builder(100) + gowrappers: strings.new_builder(100) + waiter_fn_definitions: strings.new_builder(100) + auto_str_funcs: strings.new_builder(100) + comptime_definitions: strings.new_builder(100) + pcs_declarations: strings.new_builder(100) + cov_declarations: strings.new_builder(100) + hotcode_definitions: strings.new_builder(100) + embedded_data: strings.new_builder(1000) + out_options_forward: strings.new_builder(100) + out_options: strings.new_builder(100) + out_results_forward: strings.new_builder(100) + out_results: strings.new_builder(100) + shared_types: strings.new_builder(100) + shared_functions: strings.new_builder(100) + channel_definitions: strings.new_builder(100) + thread_definitions: strings.new_builder(100) + json_forward_decls: strings.new_builder(100) + enum_typedefs: strings.new_builder(100) + sql_buf: strings.new_builder(100) + cleanup: strings.new_builder(100) + table: global_g.table + pref: global_g.pref + fn_decl: unsafe { nil } + anon_fn: unsafe { nil } + indent: -1 + module_built: global_g.module_built + static_non_parallel: global_g.static_non_parallel + static_modifier: global_g.static_modifier + timers: util.new_timers( should_print: global_g.timers_should_print label: 'cgen_process_one_file_cb idx: ${idx}, wid: ${wid}' ) - inner_loop: &ast.empty_stmt - field_data_type: global_g.table.find_type('FieldData') - enum_data_type: global_g.table.find_type('EnumData') - variant_data_type: global_g.table.find_type('VariantData') - array_sort_fn: global_g.array_sort_fn - waiter_fns: global_g.waiter_fns - threaded_fns: global_g.threaded_fns - str_fn_names: global_g.str_fn_names - anon_fns: global_g.anon_fns - options_forward: global_g.options_forward - results_forward: global_g.results_forward - done_options: global_g.done_options - done_results: global_g.done_results - late_chan_types: global_g.late_chan_types - is_autofree: global_g.pref.autofree - obf_table: global_g.obf_table - referenced_fns: global_g.referenced_fns - is_cc_msvc: global_g.is_cc_msvc - use_segfault_handler: global_g.use_segfault_handler - done_typedef_phase: global_g.done_typedef_phase - array_typedefs: global_g.array_typedefs.clone() - written_array_typedefs: global_g.written_array_typedefs - has_reflection: 'v.reflection' in global_g.table.modules - has_debugger: 'v.debug' in global_g.table.modules - reflection_strings: global_g.reflection_strings - generated_map_key_fns: map[ast.Type]bool{} + inner_loop: &ast.empty_stmt + field_data_type: global_g.table.find_type('FieldData') + enum_data_type: global_g.table.find_type('EnumData') + variant_data_type: global_g.table.find_type('VariantData') + array_sort_fn: global_g.array_sort_fn + generated_array_interface_cast_fns: global_g.generated_array_interface_cast_fns + waiter_fns: global_g.waiter_fns + threaded_fns: global_g.threaded_fns + str_fn_names: global_g.str_fn_names + anon_fns: global_g.anon_fns + options_forward: global_g.options_forward + results_forward: global_g.results_forward + done_options: global_g.done_options + done_results: global_g.done_results + late_chan_types: global_g.late_chan_types + is_autofree: global_g.pref.autofree + obf_table: global_g.obf_table + referenced_fns: global_g.referenced_fns + is_cc_msvc: global_g.is_cc_msvc + use_segfault_handler: global_g.use_segfault_handler + done_typedef_phase: global_g.done_typedef_phase + array_typedefs: global_g.array_typedefs.clone() + written_array_typedefs: global_g.written_array_typedefs + has_reflection: 'v.reflection' in global_g.table.modules + has_debugger: 'v.debug' in global_g.table.modules + reflection_strings: global_g.reflection_strings + generated_map_key_fns: map[ast.Type]bool{} } g.type_resolver = type_resolver.TypeResolver.new(global_g.table, g) g.comptime = &g.type_resolver.info diff --git a/vlib/v/tests/modules/interface_array_concat_from_another_module/main_test.v b/vlib/v/tests/modules/interface_array_concat_from_another_module/main_test.v new file mode 100644 index 000000000..52b2a1460 --- /dev/null +++ b/vlib/v/tests/modules/interface_array_concat_from_another_module/main_test.v @@ -0,0 +1,42 @@ +module main + +import arrays +import interface_array_concat_from_another_module.mod + +fn test_imported_empty_interface_array_concat_string() { + mut params := []mod.Value{} + params = arrays.concat(params, 'hello') + assert params == [mod.Value('hello')] +} + +fn test_imported_empty_interface_array_concat_bytes() { + bytes := [u8(1), 2, 3] + mut params := []mod.Value{} + params = arrays.concat(params, bytes) + assert params.len == 1 + assert params[0] as []u8 == bytes +} + +fn collect(values ...mod.Value) []mod.Value { + return values +} + +fn build_params(include_role bool) []mod.Value { + user_id_bin := [u8(1), 2, 3] + password_hash := [u8(4), 5, 6] + password_salt := [u8(7), 8, 9] + mut params := [mod.Value(user_id_bin), 'user-id', 'email@example.com', password_hash, + password_salt] + if include_role { + params = arrays.concat(params, 'admin') + } + return params +} + +fn test_imported_empty_interface_array_literal_and_variadic_forwarding() { + params := build_params(true) + got := collect(...params) + assert got.len == 6 + assert got[0] as []u8 == [u8(1), 2, 3] + assert got[5] as string == 'admin' +} diff --git a/vlib/v/tests/modules/interface_array_concat_from_another_module/mod/mod.v b/vlib/v/tests/modules/interface_array_concat_from_another_module/mod/mod.v new file mode 100644 index 000000000..8e3e67baf --- /dev/null +++ b/vlib/v/tests/modules/interface_array_concat_from_another_module/mod/mod.v @@ -0,0 +1,3 @@ +module mod + +pub interface Value {} -- 2.39.5