From: Harishankar Date: Thu, 22 Jan 2026 13:43:30 +0000 (+0530) Subject: gccrs: ast: Fix module path resolution for sibling modules in root X-Git-Tag: basepoints/gcc-17~1005 X-Git-Url: http://git.ipfire.org/gitweb/?a=commitdiff_plain;h=e429012267c30f23c416bfa2db41d92abe472d18;p=thirdparty%2Fgcc.git gccrs: ast: Fix module path resolution for sibling modules in root Currently, the compiler fails to resolve module paths when a file in the root directory (e.g. 'bar.rs') attempts to load a sibling module (e.g. 'foo.rs') if a 'bar/' directory does not exist. The compiler incorrectly assumes that if 'bar.rs' is not 'mod.rs', it must look exclusively in a subdirectory. This patch adds a fallback mechanism in 'Module::process_file_path'. If the subdirectory search fails, it strips the implicit subdirectory and attempts to resolve the module in the parent directory, consistent with Rust 2018 path rules. Fixes Rust-GCC/gccrs#4402 gcc/rust/ChangeLog: * ast/rust-ast.cc (Module::process_file_path): Add fallback search for sibling modules when subdirectory search fails. gcc/testsuite/ChangeLog: * rust/compile/issue-4402.rs: New test. * rust/compile/issue_4402_foo.rs: New test. * rust/compile/compile.exp:Ignore issue_4402_foo.rs Signed-off-by: Harishankar --- diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc index 37c38494968..9813e779500 100644 --- a/gcc/rust/ast/rust-ast.cc +++ b/gcc/rust/ast/rust-ast.cc @@ -3418,9 +3418,13 @@ Module::process_file_path () auto path_string = filename_from_path_attribute (get_outer_attrs ()); std::string including_subdir; + bool subdir_was_added = false; if (path_string.empty () && module_scope.empty () && get_file_subdir (including_fname, including_subdir)) - current_directory_name += including_subdir + file_separator; + { + current_directory_name += including_subdir + file_separator; + subdir_was_added = true; + } // Handle inline module declarations adding path components. for (auto const &name : module_scope) @@ -3449,6 +3453,28 @@ Module::process_file_path () + file_separator + expected_dir_path; bool dir_mod_found = file_exists (dir_mod_path); + if (!file_mod_found && !dir_mod_found && subdir_was_added) + { + size_t suffix_len + = including_subdir.length () + std::string (file_separator).length (); + std::string fallback_dir + = current_directory_name.substr (0, current_directory_name.length () + - suffix_len); + std::string fallback_file = fallback_dir + expected_file_path; + std::string fallback_dir_mod = fallback_dir + module_name.as_string () + + file_separator + expected_dir_path; + if (file_exists (fallback_file)) + { + file_mod_found = true; + file_mod_path = fallback_file; + } + else if (file_exists (fallback_dir_mod)) + { + dir_mod_found = true; + dir_mod_path = fallback_dir_mod; + } + } + bool multiple_candidates_found = file_mod_found && dir_mod_found; bool no_candidates_found = !file_mod_found && !dir_mod_found; diff --git a/gcc/testsuite/rust/compile/compile.exp b/gcc/testsuite/rust/compile/compile.exp index 2c3be80b014..41941316d4e 100644 --- a/gcc/testsuite/rust/compile/compile.exp +++ b/gcc/testsuite/rust/compile/compile.exp @@ -28,8 +28,21 @@ dg-init set saved-dg-do-what-default ${dg-do-what-default} set dg-do-what-default "compile" -dg-runtest [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] "" "" + +set tests [lsort [glob -nocomplain $srcdir/$subdir/*.rs]] +set ignore_list [list "issue_4402_foo.rs"] + +set tests_to_run [list] +foreach t $tests { + set filename [file tail $t] + if {[lsearch -exact $ignore_list $filename] == -1} { + lappend tests_to_run $t + } +} + +dg-runtest $tests_to_run "" "" + set dg-do-what-default ${saved-dg-do-what-default} # All done. -dg-finish +dg-finish \ No newline at end of file diff --git a/gcc/testsuite/rust/compile/issue-4402.rs b/gcc/testsuite/rust/compile/issue-4402.rs new file mode 100644 index 00000000000..0434e12bfbd --- /dev/null +++ b/gcc/testsuite/rust/compile/issue-4402.rs @@ -0,0 +1,9 @@ +#![feature(no_core)] +#![no_core] +use issue_4402_foo::Bar; +pub mod issue_4402_foo; + +fn main() { + // use '_a' to silence the unused variable warning + let _a = Bar; +} \ No newline at end of file diff --git a/gcc/testsuite/rust/compile/issue_4402_foo.rs b/gcc/testsuite/rust/compile/issue_4402_foo.rs new file mode 100644 index 00000000000..96266300d11 --- /dev/null +++ b/gcc/testsuite/rust/compile/issue_4402_foo.rs @@ -0,0 +1 @@ +pub struct Bar; \ No newline at end of file