Skip to content

Commit 1056418

Browse files
committed
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 #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. Signed-off-by: Harishankar <[email protected]>
1 parent 90ca1f6 commit 1056418

File tree

3 files changed

+39
-1
lines changed

3 files changed

+39
-1
lines changed

gcc/rust/ast/rust-ast.cc

Lines changed: 27 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3418,9 +3418,13 @@ Module::process_file_path ()
34183418
auto path_string = filename_from_path_attribute (get_outer_attrs ());
34193419

34203420
std::string including_subdir;
3421+
bool subdir_was_added = false;
34213422
if (path_string.empty () && module_scope.empty ()
34223423
&& get_file_subdir (including_fname, including_subdir))
3423-
current_directory_name += including_subdir + file_separator;
3424+
{
3425+
current_directory_name += including_subdir + file_separator;
3426+
subdir_was_added = true;
3427+
}
34243428

34253429
// Handle inline module declarations adding path components.
34263430
for (auto const &name : module_scope)
@@ -3449,6 +3453,28 @@ Module::process_file_path ()
34493453
+ file_separator + expected_dir_path;
34503454
bool dir_mod_found = file_exists (dir_mod_path);
34513455

3456+
if (!file_mod_found && !dir_mod_found && subdir_was_added)
3457+
{
3458+
size_t suffix_len
3459+
= including_subdir.length () + std::string (file_separator).length ();
3460+
std::string fallback_dir
3461+
= current_directory_name.substr (0, current_directory_name.length ()
3462+
- suffix_len);
3463+
std::string fallback_file = fallback_dir + expected_file_path;
3464+
std::string fallback_dir_mod = fallback_dir + module_name.as_string ()
3465+
+ file_separator + expected_dir_path;
3466+
if (file_exists (fallback_file))
3467+
{
3468+
file_mod_found = true;
3469+
file_mod_path = fallback_file;
3470+
}
3471+
else if (file_exists (fallback_dir_mod))
3472+
{
3473+
dir_mod_found = true;
3474+
dir_mod_path = fallback_dir_mod;
3475+
}
3476+
}
3477+
34523478
bool multiple_candidates_found = file_mod_found && dir_mod_found;
34533479
bool no_candidates_found = !file_mod_found && !dir_mod_found;
34543480

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
#![feature(no_core)]
2+
#![no_core]
3+
use issue_4402_foo::Bar;
4+
pub mod issue_4402_foo;
5+
6+
fn main() {
7+
// use '_a' to silence the unused variable warning
8+
let _a = Bar;
9+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
#![feature(no_core)]
2+
#![no_core]
3+
pub struct Bar;

0 commit comments

Comments
 (0)