From 823f10d197d94ee34be10ca037fef2ceef38274d Mon Sep 17 00:00:00 2001 From: Alexander Medvednikov Date: Thu, 23 Apr 2026 22:05:57 +0300 Subject: [PATCH] v.util: fix unknown function: cli004.sub.greetings (fixes #26828) --- .../tests/projects_that_should_compile_test.v | 20 ++++++++++++++ vlib/v/util/module.v | 1 + vlib/v/util/util_test.v | 27 +++++++++++++++++++ 3 files changed, 48 insertions(+) diff --git a/vlib/v/tests/projects_that_should_compile_test.v b/vlib/v/tests/projects_that_should_compile_test.v index 6405fc0b6..342857fbf 100644 --- a/vlib/v/tests/projects_that_should_compile_test.v +++ b/vlib/v/tests/projects_that_should_compile_test.v @@ -183,6 +183,26 @@ fn test_module_resolution_is_independent_of_working_directory() { assert res_app.trim_space() == 'Hello 16!' } +fn test_running_project_from_its_own_vmod_with_parent_vmod_works_issue_26828() { + root := os.join_path(os.vtmp_dir(), 'v_issue_26828_${os.getpid()}') + os.rmdir_all(root) or {} + defer { + os.rmdir_all(root) or {} + } + project_root := os.join_path(root, 'outer') + module_root := os.join_path(project_root, 'cli004') + os.mkdir_all(os.join_path(module_root, 'sub'))! + os.write_file(os.join_path(project_root, 'v.mod'), "Module {\n\tname: 'outer'\n}\n")! + os.write_file(os.join_path(module_root, 'v.mod'), "Module {\n\tname: 'cli004'\n}\n")! + os.write_file(os.join_path(module_root, 'cli004.v'), + 'module main\n\nimport sub\n\nfn main() {\n\tsub.greetings()\n}\n')! + os.write_file(os.join_path(module_root, 'sub', 'hey.v'), + "module sub\n\npub fn greetings() {\n\tprintln('greetings from sub')\n}\n")! + + res := vrun_ok_in_dir(module_root, 'crun', '.') + assert res.trim_space() == 'greetings from sub' +} + fn test_custom_print_should_compile_with_no_builtin() { source_path := os.join_path(os.vtmp_dir(), 'custom_print_no_builtin_${os.getpid()}.v') output_path := os.join_path(os.vtmp_dir(), 'custom_print_no_builtin_${os.getpid()}.c') diff --git a/vlib/v/util/module.v b/vlib/v/util/module.v index 188b5dc71..daba56064 100644 --- a/vlib/v/util/module.v +++ b/vlib/v/util/module.v @@ -166,6 +166,7 @@ fn mod_path_to_full_name(pref_ &pref.Preferences, mod string, path string) !stri if 'v.mod' in ls && (try_path_parts.len > i && try_path_parts[i] != 'v' && 'vlib' !in ls) { last_v_mod = j + break } continue } diff --git a/vlib/v/util/util_test.v b/vlib/v/util/util_test.v index 2b87e69fb..2c81c875c 100644 --- a/vlib/v/util/util_test.v +++ b/vlib/v/util/util_test.v @@ -2,6 +2,7 @@ module util import os import time +import v.pref fn test_tool_recompilation_args_force_system_cc_for_vdoc_on_freebsd() { assert tool_recompilation_args('vdoc', 'freebsd') == ['-cc', 'cc'] @@ -127,3 +128,29 @@ fn test_vlines_escape_path_does_not_restore_old_tcc_prefix_workaround() { assert escaped_tcc_path.starts_with(os.windows_volume(source_path)) } } + +fn test_qualify_import_stops_at_nearest_vmod_issue_26828() { + root := os.join_path(os.vtmp_dir(), 'v_qualify_import_issue_26828_${os.getpid()}') + os.rmdir_all(root) or {} + defer { + os.rmdir_all(root) or {} + } + project_root := os.join_path(root, 'outer') + module_root := os.join_path(project_root, 'cli004') + os.mkdir_all(os.join_path(module_root, 'sub'))! + os.write_file(os.join_path(project_root, 'v.mod'), "Module {\n\tname: 'outer'\n}\n")! + os.write_file(os.join_path(module_root, 'v.mod'), "Module {\n\tname: 'cli004'\n}\n")! + main_file := os.join_path(module_root, 'cli004.v') + os.write_file(main_file, 'module main\n\nimport sub\n\nfn main() {}\n')! + + mut p := pref.new_preferences() + p.path = '.' + old_dir := os.getwd() + defer { + os.chdir(old_dir) or { panic(err) } + } + os.chdir(module_root)! + + assert qualify_import(p, 'sub', main_file) == 'sub' + assert qualify_import(p, 'sub', 'cli004.v') == 'sub' +} -- 2.39.5