In a workspace where one package uses rust edition 2021 and another one uses rust edition 2024, cargo fmt -- <file> attempts to format that file with both editions. If the file uses a 2024-only feature like a let chain, this fails.
The reason this comes up in practice is that the pre-commit hook fmt calls cargo fmt -- <files changed by commit>, which seems like a reasonable thing to do.
$ cargo fmt --verbose -- newapp/src/main.rs
[bin (2024)] "/kdab/src/rust/fmt-bug/newapp/src/main.rs"
[bin (2021)] "/kdab/src/rust/fmt-bug/oldapp/src/main.rs"
rustfmt --edition 2021 newapp/src/main.rs /kdab/src/rust/fmt-bug/oldapp/src/main.rs
error: let chains are only allowed in Rust 2024 or later
--> /kdab/src/rust/fmt-bug/newapp/src/main.rs:3:8
|
3 | if let Some(val) = opt
| ^^^^^^^^^^^^^^^^^^^
rustfmt --edition 2024 newapp/src/main.rs /kdab/src/rust/fmt-bug/newapp/src/main.rs
To reproduce this:
git clone https://github.com/dfaure-kdab/cargo-fmt-bug
cd cargo-fmt-bug
cargo fmt --verbose -- newapp/src/main.rs
run_rustfmt() just passes along the fmt_args to all calls to rustfmt, without realizing that if the argument is a filename then it should filter it based on the edition...