Skip to content

Commit

Permalink
Improve out of line module resolution
Browse files Browse the repository at this point in the history
Fixes 5119

When the directory structure was laid out as follows:

```
dir
 |---mod_a
 |    |---sub_mod_1.rs
 |    |---sub_mod_2.rs
 |---mod_a.rs
```

And ``mod_a.rs`` contains the following content:

```rust
mod mod_a {
    mod sub_mod_1;
    mod sub_mod_2;
}
```

rustfmt previously tried to find ``sub_mod_1.rs`` and ``sub_mod_2.rs``
in ``./mod_a/mod_a/``. This directory does not exist and this caused
rustfmt to fail with the error message:

    Error writing files: failed to resolve mod

Now, both ``sub_mod_1.rs`` and ``sub_mod_2.rs`` are resolved correctly
and found at ``mod_a/sub_mod_1.rs`` and ``mod_a/sub_mod_2.rs``.
  • Loading branch information
ytmimi committed Dec 20, 2021
1 parent 57ac92b commit 77feb51
Show file tree
Hide file tree
Showing 8 changed files with 75 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -458,6 +458,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
self.directory.path.push(&*path.as_str());
self.directory.ownership = DirectoryOwnership::Owned { relative: None };
} else {
let id = &*id.as_str();
// We have to push on the current module name in the case of relative
// paths in order to ensure that any additional module paths from inline
// `mod x { ... }` come after the relative extension.
Expand All @@ -468,9 +469,15 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
if let Some(ident) = relative.take() {
// remove the relative offset
self.directory.path.push(&*ident.as_str());

// In the case where there is an x.rs and an ./x directory we want
// to prevent adding x twice. For example, ./x/x
if self.directory.path.exists() && !self.directory.path.join(id).exists() {
return;
}
}
}
self.directory.path.push(&*id.as_str());
self.directory.path.push(id);
}
}

Expand Down
13 changes: 13 additions & 0 deletions src/test/mod_resolver.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,16 @@ fn skip_out_of_line_nested_inline_within_out_of_line() {
&["tests/mod-resolver/skip-files-issue-5065/one.rs"],
);
}

#[test]
fn fmt_out_of_line_test_modules() {
// See also https://github.com/rust-lang/rustfmt/issues/5119
verify_mod_resolution(
"tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs",
&[
"tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs",
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs",
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs",
],
)
}
23 changes: 23 additions & 0 deletions tests/cargo-fmt/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

use std::env;
use std::process::Command;
use std::path::Path;

/// Run the cargo-fmt executable and return its output.
fn cargo_fmt(args: &[&str]) -> (String, String) {
Expand Down Expand Up @@ -71,3 +72,25 @@ fn rustfmt_help() {
assert_that!(&["--", "-h"], contains("Format Rust code"));
assert_that!(&["--", "--help=config"], contains("Configuration Options:"));
}

#[test]
fn cargo_fmt_out_of_line_test_modules() {
// See also https://github.com/rust-lang/rustfmt/issues/5119
let expected_modified_files = [
"tests/mod-resolver/test-submodule-issue-5119/src/lib.rs",
"tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs",
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub1.rs",
"tests/mod-resolver/test-submodule-issue-5119/tests/test1/sub2.rs",
];
let args = [
"-v",
"--check",
"--manifest-path",
"tests/mod-resolver/test-submodule-issue-5119/Cargo.toml",
];
let (stdout, _) = cargo_fmt(&args);
for file in expected_modified_files {
let path = Path::new(file).canonicalize().unwrap();
assert!(stdout.contains(&format!("Diff in {}", path.display())))
}
}
8 changes: 8 additions & 0 deletions tests/mod-resolver/test-submodule-issue-5119/Cargo.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
[package]
name = "rustfmt-test-submodule-issue"
version = "0.1.0"
edition = "2018"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
7 changes: 7 additions & 0 deletions tests/mod-resolver/test-submodule-issue-5119/src/lib.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
pub fn foo() -> i32 {
3
}

pub fn bar() -> i32 {
4
}
4 changes: 4 additions & 0 deletions tests/mod-resolver/test-submodule-issue-5119/tests/test1.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
mod test1 {
mod sub1;
mod sub2;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use rustfmt_test_submodule_issue::foo;

#[test]
fn test_foo() {
assert_eq!(3, foo());
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
use rustfmt_test_submodule_issue::bar;

#[test]
fn test_bar() {
assert_eq!(4, bar());
}

0 comments on commit 77feb51

Please sign in to comment.