Description
rustfmt
will inspect the files it is passed for mod
statements, and will recursively traverse them to format entire crates. cargo fmt
relies on this too, passing src/lib.rs
to get an entire library crate formatted. Unfortunately, rustfmt
misses submodules if their mod
statements come from macro expansions. For example:
src/main.rs
:
macro_rules! foo {
() => {
mod bar;
};
}
foo!();
fn main() {
println!("Hello, world!");
println!("{}", bar::foo(42));
}
src/bar.rs
:
pub fn foo
(a: u8)
-> u8
{ a }
Steps:
cargo new --bin macro-expn-bug
cd macro-expn-bug
- Set up
src/main.rs
andsrc/bar.rs
as above cargo fmt --check
Expected output:
rustfmt --check --edition 2021 src/bar.rs
Diff in /tmp/rustfmt-bug/src/bar.rs:1:
-pub fn foo
-(a: u8)
--> u8
-{ a }
+pub fn foo(a: u8) -> u8 {
+ a
+}
Actual output: empty.
We assumed this behavior would work in a production Rust library (https://github.com/NLnetLabs/domain), and misformatted source files have laid dormant in the codebase for over a year. From a practical perspective, I understand that fixing this will not be easy; but silently succeeding isn't okay. Perhaps rustfmt
can compare the list of files it traversed to the list of files traversed by cargo check
or similar? I'm also not sure how this interacts with feature flags.