From: Harishankar <[email protected]>
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 <[email protected]>
---
This change was merged into the gccrs repository and is posted here for
upstream visibility and potential drive-by review, as requested by GCC
release managers.
Each commit email contains a link to its details on github from where you can
find the Pull-Request and associated discussions.
Commit on github:
https://github.com/Rust-GCC/gccrs/commit/dc07f2a2bb4e8aae8c5148515f922de8a7ca12e2
The commit has been mentioned in the following pull-request(s):
- https://github.com/Rust-GCC/gccrs/pull/4406
gcc/rust/ast/rust-ast.cc | 28 +++++++++++++++++++-
gcc/testsuite/rust/compile/compile.exp | 17 ++++++++++--
gcc/testsuite/rust/compile/issue-4402.rs | 9 +++++++
gcc/testsuite/rust/compile/issue_4402_foo.rs | 1 +
4 files changed, 52 insertions(+), 3 deletions(-)
create mode 100644 gcc/testsuite/rust/compile/issue-4402.rs
create mode 100644 gcc/testsuite/rust/compile/issue_4402_foo.rs
diff --git a/gcc/rust/ast/rust-ast.cc b/gcc/rust/ast/rust-ast.cc
index 37c384949..9813e7795 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 2c3be80b0..41941316d 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 000000000..0434e12bf
--- /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 000000000..96266300d
--- /dev/null
+++ b/gcc/testsuite/rust/compile/issue_4402_foo.rs
@@ -0,0 +1 @@
+pub struct Bar;
\ No newline at end of file
base-commit: b98bdc90724f24e7458b7209499c5a7261afe258
--
2.52.0