Skip to content

feat: add ignore_missing_submod option #5611

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Configurations.md
Original file line number Diff line number Diff line change
Expand Up @@ -1306,6 +1306,15 @@ If you want to ignore every file under the directory where you put your rustfmt.
ignore = ["/"]
```

## `ignore_missing_submod`

Ignore missing submodule error.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we need to elaborate on this description. I think we should explain that normally missing modules will lead to module not found errors and rustfmt won't format anything.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. Most of the messages you wrote are used, but I added "By default" at the beginning of the sentence to clarify the behavior by default.

By default, missing modules will lead to module not found errors and rustfmt won't format anything.

- **Default value**: `false`
- **Possible values**: `true`, `false`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On thing the team has discussed is moving away from a binary error model. I think if we land this, I'd like to change from true and false to something like Warn, Error, Ignore. With that in mind I think it a more appropriate name would be something like report_missing_submod. Let me know if you can come up with anything better!

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Update Configuration.md on this commit. 4bb0453

- **Stable**: No

## `imports_indent`

Indent style of imports
Expand Down
2 changes: 2 additions & 0 deletions src/config/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -179,6 +179,7 @@ create_config! {
or they are left with trailing whitespaces";
ignore: IgnoreList, IgnoreList::default(), false,
"Skip formatting the specified files and directories";
ignore_missing_submod: bool, false, false, "Ignore missing submodule error";

// Not user-facing
verbose: Verbosity, Verbosity::Normal, false, "How much to information to emit to the user";
Expand Down Expand Up @@ -697,6 +698,7 @@ show_parse_errors = true
error_on_line_overflow = false
error_on_unformatted = false
ignore = []
ignore_missing_submod = false
emit_mode = "Files"
make_backup = false
"#,
Expand Down
1 change: 1 addition & 0 deletions src/formatting.rs
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,7 @@ fn format_project<T: FormatHandler>(
&context.parse_session,
directory_ownership.unwrap_or(DirectoryOwnership::UnownedViaBlock),
!input_is_stdin && !config.skip_children(),
config.ignore_missing_submod(),
)
.visit_crate(&krate)?
.into_iter()
Expand Down
11 changes: 11 additions & 0 deletions src/modules.rs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@ pub(crate) struct ModResolver<'ast, 'sess> {
directory: Directory,
file_map: FileModMap<'ast>,
recursive: bool,
ignore_missing_submod: bool,
}

/// Represents errors while trying to resolve modules.
Expand Down Expand Up @@ -105,6 +106,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
parse_sess: &'sess ParseSess,
directory_ownership: DirectoryOwnership,
recursive: bool,
ignore_missing_submod: bool,
) -> Self {
ModResolver {
directory: Directory {
Expand All @@ -114,6 +116,7 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
file_map: BTreeMap::new(),
parse_sess,
recursive,
ignore_missing_submod,
}
}

Expand Down Expand Up @@ -249,6 +252,14 @@ impl<'ast, 'sess, 'c> ModResolver<'ast, 'sess> {
// mod foo;
// Look for an extern file.
self.find_external_module(item.ident, &item.attrs, sub_mod)
.or_else(|err| match err.kind {
ModuleResolutionErrorKind::NotFound { file: _ }
if self.ignore_missing_submod =>
{
Ok(None)
}
_ => Err(err),
})
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd like to rework this with Error, Warn, and Ignore variants in mind. I think the only difference is that if Warn is set we'll emit an error message, but still continue with Ok(None).

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for the review! When emitting a message for a 'warn', is it sufficient to simply use eprintln! to output to stderr? Or is there a more appropriate method you could suggest?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed. f678369

For now, I implemented direct output with eprintln.
(However, I think I might be better off using FormatReport.)

} else {
// An internal module (`mod foo { /* ... */ }`);
Ok(Some(SubModKind::Internal(item)))
Expand Down
31 changes: 29 additions & 2 deletions tests/rustfmt/main.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
//! Integration tests for rustfmt.

use std::env;
use std::fs::remove_file;
use std::path::Path;
use std::fs::{read_to_string, remove_file};
use std::path::{Path, PathBuf};
use std::process::Command;

use rustfmt_config_proc_macro::rustfmt_only_ci_test;
Expand Down Expand Up @@ -200,3 +200,30 @@ fn rustfmt_emits_error_when_control_brace_style_is_always_next_line() {
let (_stdout, stderr) = rustfmt(&args);
assert!(!stderr.contains("error[internal]: left behind trailing whitespace"))
}

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

will likely need to rework the tests slightly to accommodate Error, Warn, and Ignore variants.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed test on this commit. fcc06f9

#[test]
fn ignore_missing_sub_mod_false() {
// Ensure that missing submodules cause module not found errors when trying to
// resolve submodules with `skip_children=false` and `ignore_missing_submod=false`
let args = [
"--config=skip_children=false,ignore_missing_submod=false",
"tests/source/issue-5609.rs",
];
let (_stdout, stderr) = rustfmt(&args);
// Module resolution fails because we're unable to find `missing_submod.rs`
assert!(stderr.contains("missing_submod.rs does not exist"))
}

#[test]
fn ignore_missing_sub_mod_true() {
// Ensure that missing submodules don't cause module not found errors when trying to
// resolve submodules with `skip_children=false` and `ignore_missing_submod=true`.
let args = [
"--emit=stdout",
"--config=skip_children=false,ignore_missing_submod=true",
"tests/source/issue-5609.rs",
];
let (stdout, _stderr) = rustfmt(&args);
let target = read_to_string(PathBuf::from("tests/target/issue-5609.rs")).unwrap();
assert!(stdout.ends_with(&target));
}
8 changes: 8 additions & 0 deletions tests/source/issue-5609.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
// rustfmt-ignore_missing_submod: true
// rustfmt-skip_children: false

mod missing_submod;

fn test() {

}
6 changes: 6 additions & 0 deletions tests/target/issue-5609.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
// rustfmt-ignore_missing_submod: true
// rustfmt-skip_children: false

mod missing_submod;

fn test() {}